c# 中的“operator true”是否正好有两个可以使用的地方?

Bet*_*ker 7 c# boolean operator-overloading

c# 允许您覆盖类的“operator true”和“operator false”:

class Foo
{
   bool Thing;

   Foo(bool thing)
   {
      Thing = thing;
   }

   public static bool operator true(Foo foo) => foo.Thing;
   public static bool operator false(Foo foo) => !foo.Thing;
}
Run Code Online (Sandbox Code Playgroud)

它有点工作。你可以说

Foo foo = new Foo(true);
if (foo)
   Stuff();
string s = foo ? "yes" : "no";
Run Code Online (Sandbox Code Playgroud)

但你不能说

Foo foo = new Foo(true);
bool boo = true;
if (boo && foo)
   Stuff();
if (boo & foo)
   Stuff();
if (boo & (foo == true))
   Stuff();
if (boo & ((bool)foo))
   Stuff();
Foo foo2 = new Foo(true);
if (foo && foo2)
   Stuff();
if (foo & foo2)
   Stuff();
if (foo == boo)
   Stuff();
if (foo != boo)
   Stuff();
bool boo2 = foo;
Run Code Online (Sandbox Code Playgroud)

在每种情况下,编译器都会抱怨。

除了那些非常具体的语法之外,c# 编译器是否在任何地方使用“operator true”和“operator false”?

编辑

我又找到了一个“operator true”和“operator false”起作用的地方。如果您定义了一个“operator&”,除了真假运算符之外还返回 Foo,编译器将采用表达式“foo1 && foo2”并假装您编写了“foo1 & foo2”,因此调用您的重写运算符。换句话说,“operator true”和“operator false”的存在会改变编译器的行为,即使它从不调用这些运算符

Swe*_*per 8

c# 中的“operator true”是否正好有两个可以使用的地方?

不完全是。您可以在C# 语言规范中搜索“operator true”(我做了)并查看它的作用。第7.12.27.147.20 节提到了它。7.14 本质上是关于你已经知道的三元运算符,但在 7.20 中,它说

Aboolean-expression是产生 bool 类型结果的表达式;直接或通过true在以下指定的某些上下文中应用运算符。

if-statement(§8.7.1)、 while-statement(§8.8.1)、do-statement(§8.8.2) 或for-statement (§8.8.3)的控制条件表达式是 a boolean-expression

所以,不只是在一个if声明,而且在一whiledofor以及。

在 7.12.2 中,它说:

&&或的操作数||属于声明适用的用户定义运算符 &或运算符 的类型时,|以下两项都必须为真,其中T是声明所选运算符的类型:

  • 所选运算符的返回类型和每个参数的类型必须是T. 换句话说,运算符必须计算两个 type 操作数的逻辑 AND 或逻辑 OR T,并且必须返回 type 的结果T
  • T必须包含 operatortrue和 operator 的声明false

因此,&& 可以在您的自定义类型一起使用,如果你也声明&


编辑:

刚刚找到这个链接,它总结得很清楚。


换句话说,“operator true”和“operator false”的存在改变了编译器的行为,即使它从不调用这些运算符。

确实调用了这些运算符。根据语言规范 7.12.2:

操作x && y被评价为T.false(x) ? x : T.&(x, y),其中T.false(x)是操作者的调用false中声明T,并且T.&(x, y)是所选择的操作者的调用&。换句话说,x首先评估并false在结果上调用运算符以确定是否x肯定是false。然后,如果x肯定false是 ,则运算的结果是先前为 计算的值x。否则,y会求值,并对&先前计算x的值和计算的值调用所选运算符y以生成操作结果。

基本上,由于&&是短路,它必须通过使用false运算符知道其操作数之一是否为假。

那么为什么语言设计者要创建“operator true”和“operator false”呢?

这里解释得很好,我认为:

true运算符返回 bool 值true以指示其操作数肯定为真。该false运算符返回 bool 值true以指示其操作数肯定为假。

它基本上适用于您希望自定义类型具有真/假值的情况。将LaunchStatus在同一链路和类型DBBool类型这里是很好的例证。