关于.net:C#中的false运算符有什么用呢?

关于.net:C#中的false运算符有什么用呢?

What's the false operator in C# good for?

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#中的错误运算符是什么?

注意:此处和此处可以找到更多示例。


您可以使用它来覆盖&&||运算符。

无法覆盖&&||运算符,但如果以完全正确的方式覆盖|&truefalse,编译器将调用|&当你写||&&时。

例如,看看这段代码(来自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不会起作用;你必须超载!怪事!


推荐阅读