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”的存在会改变编译器的行为,即使它从不调用这些运算符。
c# 中的“operator true”是否正好有两个可以使用的地方?
不完全是。您可以在C# 语言规范中搜索“operator true”(我做了)并查看它的作用。第7.12.2、7.14、7.20 节提到了它。7.14 本质上是关于你已经知道的三元运算符,但在 7.20 中,它说
A
boolean-expression是产生 bool 类型结果的表达式;直接或通过true在以下指定的某些上下文中应用运算符。
if-statement(§8.7.1)、while-statement(§8.8.1)、do-statement(§8.8.2) 或for-statement(§8.8.3)的控制条件表达式是 aboolean-expression。
所以,不只是在一个if声明,而且在一while,do,for以及。
在 7.12.2 中,它说:
当
&&或的操作数||属于声明适用的用户定义运算符&或运算符 的类型时,|以下两项都必须为真,其中T是声明所选运算符的类型:
- 所选运算符的返回类型和每个参数的类型必须是
T. 换句话说,运算符必须计算两个 type 操作数的逻辑 AND 或逻辑 ORT,并且必须返回 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类型这里是很好的例证。