简体   繁体   English

什么是C#中的错误操作符?

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

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. 但是,对于上面的所有示例,仅执行true运算符。 So what's the false operator in C# good for? 那么C#中的错误运算符是什么?

Note: More examples can be found here , here and here . 注:更多的例子可以发现在这里这里这里

You can use it to override the && and || 您可以使用它来覆盖&&|| operators. 运营商。

The && and || &&|| operators can't be overridden, but if you override | 运算符不能被覆盖,但如果覆盖| , & , true and false in exactly the right way the compiler will call | &truefalse完全正确的方式编译器会调用| and & when you write || &当你写|| and && . &&

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 version by @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. 这显然是副作用,而不是它的预期使用方式,但它很有用。

Shog9 and Nir: thanks for your answers. Shog9和Nir:谢谢你的回答。 Those answers pointed me to Steve Eichert article and it pointed me to msdn : 那些答案向我指出了Steve Eichert的文章 ,它指向了msdn

The operation x && y is evaluated as T.false(x) ? 操作x && y被评估为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 &. x:T。&(x,y),其中T.false(x)是在T中声明的运算符false的调用,并且T。&(x,y)是所选运算符&的调用。 In other words, x is first evaluated and operator false is invoked on the result to determine if x is definitely false. 换句话说,首先计算x并在结果上调用operator false以确定x是否肯定为false。 Then, if x is definitely false, the result of the operation is the value previously computed for x. 然后,如果x肯定是假的,则操作的结果是先前为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. 否则,计算y,并且对先前为x计算的值和为y计算的值调用所选运算符&以生成操作的结果。

The page you link to http://msdn.microsoft.com/en-us/library/6x6y6z4d.aspx says 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的页面说明了它们的用途,这是一种在引入可空值类型之前处理可空的bool的方法。

I'd guess nowadays they're good for the same sort of stuff as ArrayList - ie absolutely nothing. 我猜他们现在对ArrayList这样的东西很有用 - 也就是说什么都没有。

AFAIK, it would be used in a test for false, such as when the && operator comes into play. AFAIK,它将用于测试中的假,例如当&&运算符进入游戏时。 Remember, && short-circuits, so in the expression 请记住,&&短路,所以在表达式中

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

mFalse.false() is called, and upon returning true the 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 . 请注意,必须实现&运算符才能编译该表达式,因为如果mFalse.false()返回false ,则使用它。

It appears from the MSDN article you linked to it was provided to allow for nullable boolean types prior to the Nullable (ie int?, bool?, etc.) type being introducted into the language in C#2. 从MSDN文章看来,你链接到它是为了允许在Nullable(即int?,bool?等)类型被引入C#2语言之前的可以为空的布尔类型。 Thus you would store an internal value indicating whether the value is true or false or null, ie in your example >0 for true, <0 for false and ==0 for null, and then you'd get SQL-style null semantics. 因此,您将存储一个内部值,指示值是true还是false或null,即在您的示例中> 0表示true,<0表示false,== 0表示null,然后您将获得SQL样式的null语义。 You would also have to implement a .IsNull method or property in order that nullity could be checked explicitly. 您还必须实现.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相比,假设一个表有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, ie 3 values equal to true, 3 values equal to false and 3 values equal to null. 想象MyTypeEnumberable具有完全相同的数据库内容,即3个值等于true,3个值等于false,3个值等于null。 In this case totalCount would evaluate to 6 in this case. 在这种情况下,在这种情况下,totalCount将评估为6。 However, if we re-wrote the code as:- 但是,如果我们重新编写代码: -

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, ie indicating truth, falsity or 'otherwise'. 我相信虚假运算符会输入这些逻辑运算符,即表示真,假或“否则”。 As noted in another comment !x won't work off the bat; 正如另一条评论所指出的那样!x不会起作用; you have to overload !. 你必须超载! Weirdness! 怪事!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM