C#中有两个奇怪的运算符:
如果我理解这一点,这些运算符可以用于我想要使用的类型而不是布尔表达式,并且我不希望提供对bool的隐式转换。
假设我有以下课程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| public class MyType
{
public readonly int Value;
public MyType(int value)
{
Value = value;
}
public static bool operator true (MyType mt)
{
return mt.Value > 0;
}
public static bool operator false (MyType mt)
{
return mt.Value < 0;
}
} |
所以我可以编写以下代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| MyType mTrue = new MyType(100);
MyType mFalse = new MyType(-100);
MyType mDontKnow = new MyType(0);
if (mTrue)
{
// Do something.
}
while (mFalse)
{
// Do something else.
}
do
{
// Another code comes here.
} while (mDontKnow) |
但是,对于上面的所有示例,仅执行true运算符。 那么C#中的错误运算符是什么?
注意:此处和此处可以找到更多示例。
您可以使用它来覆盖&&和||运算符。
无法覆盖&&和||运算符,但如果以完全正确的方式覆盖|,&,true和false,编译器将调用|和&当你写||和&&时。
例如,看看这段代码(来自http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading - 我发现了这个技巧; @BiggsTRC的归档版本):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static AbstractCriterion operator &(AbstractCriterion lhs, AbstractCriterion rhs)
{
return new AndExpression(lhs, rhs);
}
public static AbstractCriterion operator |(AbstractCriterion lhs, AbstractCriterion rhs)
{
return new OrExpression(lhs, rhs);
}
public static bool operator false(AbstractCriterion criteria)
{
return false;
}
public static bool operator true(AbstractCriterion criteria)
{
return false;
} |
这显然是副作用,而不是它的预期使用方式,但它很有用。
Shog9和Nir:
谢谢你的回答。那些答案向我指出了Steve Eichert的文章,它指向了msdn:
The operation x && y is evaluated as T.false(x) ? x : T.&(x, y), where T.false(x) is an invocation of the operator false declared in T, and T.&(x, y) is an invocation of the selected operator &. In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. Then, if x is definitely false, the result of the operation is the value previously computed for x. Otherwise, y is evaluated, and the selected operator & is invoked on the value previously computed for x and the value computed for y to produce the result of the operation.
您链接到http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx的页面说明了它们的用途,这是一种在引入可空值类型之前处理可空的bool的方法。
我想现在他们对ArrayList这样的东西很有用 - 也就是说什么都没有。
AFAIK,它将用于测试中的假,例如当&&运算符进入游戏时。请记住,&&短路,所以在表达式中
1 2 3 4
| if ( mFalse && mTrue)
{
// ... something
} |
调用mFalse.false(),并且在返回true时,表达式被简化为对'mFalse.true()的调用(然后应返回false,否则事情将变得奇怪)。
请注意,必须实现&运算符才能编译该表达式,因为如果mFalse.false()返回false,则使用它。
从您链接到它的MSDN文章中可以看出,在Nullable(即int?,bool?等)类型被引入C#2语言之前允许可以为空的布尔类型。因此,您将存储一个内部值,指示值是true还是false或null,即在您的示例中> 0表示true,<0表示false,== 0表示null,然后您将获得SQL样式的null语义。您还必须实现.IsNull方法或属性,以便可以显式检查无效性。
与SQL相比,假设一个表有3行,其中值Foo设置为true,3行值Foo设置为false,3行值Foo设置为null。
1 2
| SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
6 |
为了计算所有行,您必须执行以下操作: -
1 2
| SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
9 |
这个'IS NULL'语法在你的类中将具有等效的代码为.IsNull()。
LINQ使与C#的比较更加清晰: -
1 2 3
| int totalCount = (from s in MyTypeEnumerable
where s || !s
select s).Count(); |
想象MyTypeEnumberable具有完全相同的数据库内容,即3个值等于true,3个值等于false,3个值等于null。在这种情况下,在这种情况下,totalCount将评估为6。但是,如果我们重新编写代码: -
1 2 3
| int totalCount = (from s in MyTypeEnumerable
where s || !s || s.IsNull()
select s).Count(); |
然后totalCount将评估为9。
在关于false运算符的链接MSDN文章中给出的DBNull示例演示了BCL中具有此确切行为的类。
实际上结论是你不应该使用它,除非你完全确定你想要这种类型的行为,最好只使用更简单的可以为空的语法!
更新:我刚刚注意到你需要手动覆盖逻辑运算符!,||和&&使这项工作正常。我相信虚假运算符会输入这些逻辑运算符,即表示真,假或"其他"。正如另一条评论所指出的那样!x不会起作用;你必须超载!怪事!