C# 中的 false 运算符有什么用?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/33265/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 09:13:35  来源:igfitidea点击:

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

提问by Jakub ?turc

There are two weird operators in C#:

C#中有两个奇怪的运算符:

If I understand this right these operators can be used in types which I want to use instead of a boolean expression and where I don't want to provide an implicit conversion to bool.

如果我理解这一点,这些运算符可以用于我想要使用的类型而不是布尔表达式,并且我不想提供到 bool 的隐式转换。

Let's say I have a following class:

假设我有以下课程:

    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;
        }

    }

So I can write the following code:

所以我可以编写以下代码:

    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)

However for all the examples above only the true operator is executed. So what's the false operator in C# good for?

但是,对于上面的所有示例,仅执行 true 运算符。那么 C# 中的 false 运算符有什么用呢?

Note: More examples can be found here, hereand here.

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

采纳答案by Nir

You can use it to override the &&and ||operators.

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

The &&and ||operators can't be overridden, but if you override |, &, trueand falsein exactly the right way the compiler will call |and &when you write ||and &&.

&&||运营商不能被覆盖,但如果重写|&truefalse完全正确的方式编译器会调用|&当你写||&&

For example, look at this code (from http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading- where I found out about this trick; archived versionby @BiggsTRC):

例如,看看这个代码(来自http://ayende.com/blog/1574/nhibernate-criteria-api-operator-overloading- 我在那里发现了这个技巧;@BiggsTRC存档版本):

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;
}

This is obviously a side effect and not the way it's intended to be used, but it is useful.

这显然是一种副作用,而不是它的预期使用方式,但它很有用。

回答by Will Dean

The page you link to http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspxsays what they were for, which was a way of handling nullable bools before nullable value types were introduced.

您链接到http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx的页面 说明了它们的用途,这是在引入可空值类型之前处理可空布尔值的一种方式。

I'd guess nowadays they're good for the same sort of stuff as ArrayList - i.e. absolutely nothing.

我猜现在它们适用于与 ArrayList 相同的东西 - 即绝对没有。

回答by ljs

It appears from the MSDN article you linked to it was provided to allow for nullable boolean types prior to the Nullable (i.e. int?, bool?, etc.) type being introducted into the language in C#2. Thus you would store an internal value indicating whether the value is true or false or null, i.e. in your example >0 for true, <0 for false and ==0 for null, and then you'd get SQL-style null semantics. You would also have to implement a .IsNull method or property in order that nullity could be checked explicitly.

从您链接到它的 MSDN 文章中可以看出,在将 Nullable(即 int?、bool? 等)类型引入 C#2 语言之前,允许使用可为空的布尔类型。因此,您将存储一个内部值,指示该值是真、假还是空,即在您的示例中,>0 表示真,<0 表示假,==0 表示空,然后您将获得 SQL 风格的空语义。您还必须实现 .IsNull 方法或属性,以便可以显式检查无效性。

Comparing to SQL, imagine a table Table with 3 rows with value Foo set to true, 3 rows with value Foo set to false and 3 rows with value Foo set to null.

与 SQL 相比,想象一个表 Table,其中 3 行 Foo 值设置为 true,3 行 Foo 值设置为 false,3 行 Foo 值设置为 null。

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE
6

In order to count all rows you'd have to do the following:-

为了计算所有行,您必须执行以下操作:-

SELECT COUNT(*) FROM Table WHERE Foo = TRUE OR Foo = FALSE OR Foo IS NULL
9

This 'IS NULL' syntax would have equivilent code in your class as .IsNull().

这种“IS NULL”语法在您的类中将具有与 .IsNull() 等效的代码。

LINQ makes the comparison to C# even clearer:-

LINQ 使与 C# 的比较更加清晰:-

int totalCount = (from s in MyTypeEnumerable
                 where s || !s
                 select s).Count();

Imagining that MyTypeEnumberable has exactly the same contents of the database, i.e. 3 values equal to true, 3 values equal to false and 3 values equal to null. In this case totalCount would evaluate to 6 in this case. However, if we re-wrote the code as:-

想象一下 MyTypeEnumberable 具有完全相同的数据库内容,即 3 个值等于 true,3 个值等于 false 和 3 个值等于 null。在这种情况下,在这种情况下 totalCount 将评估为 6。但是,如果我们将代码重写为:-

int totalCount = (from s in MyTypeEnumerable
                 where s || !s || s.IsNull()
                 select s).Count();

Then totalCount would evaluate to 9.

然后 totalCount 将评估为 9。

The DBNull example given in the linked MSDN article on the false operator demonstrates a class in the BCL which has this exact behaviour.

在有关 false 运算符的链接 MSDN 文章中给出的 DBNull 示例演示了 BCL 中具有这种确切行为的类。

In effect the conclusion is you shouldn't use this unless you're completely sure you want this type of behaviour, it's better to just use the far simpler nullable syntax!!

实际上结论是你不应该使用它,除非你完全确定你想要这种类型的行为,最好只使用更简单的可为空的语法!!

Update:I just noticed you need to manually override the logic operators !, || and && to make this work properly. I believe the false operator feeds into these logical operators, i.e. indicating truth, falsity or 'otherwise'. As noted in another comment !x won't work off the bat; you have to overload !. Weirdness!

更新:我刚刚注意到您需要手动覆盖逻辑运算符 !, || 和 && 以使其正常工作。我相信错误运算符会输入这些逻辑运算符,即指示真、假或“否则”。正如另一条评论中所述!x 不会立即生效;你必须超载!。奇怪!

回答by Shog9

AFAIK, it would be used in a test for false, such as when the &&operator comes into play. Remember, && short-circuits, so in the expression

AFAIK,它将用于错误的测试,例如当&&操作员发挥作用时。记住,&& 短路,所以在表达式中

if ( mFalse && mTrue) 
{
   // ... something
}

mFalse.false()is called, and upon returning truethe expression is reduced to a call to 'mFalse.true()' (which should then return false, or things will get weird).

mFalse.false()被调用,并在返回true表达式时简化为对 'mFalse.true()' 的调用(然后应该返回false,否则事情会变得奇怪)。

Note that you must implement the &operator in order for that expression to compile, since it's used if mFalse.false()returns false.

请注意,您必须实现&运算符才能编译该表达式,因为它使用 ifmFalse.false()返回false

回答by Jakub ?turc

Shog9 and Nir: thanks for your answers. Those answers pointed me to Steve Eichert articleand it pointed me to msdn:

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.

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