Why is 1 && 2 in C# false?

最后都变了- 提交于 2019-12-05 01:25:50

In C there is no bool. Convention is that 0 is false and != 0 is true. if statement treated conditional expression result exactly that way.

In C++ bool was introduced. But it was compatible with old rules, 0 treated as false and false as 0, and there was implicit conversion between int and bool.

In C# it is not the same way: there is bool and int and they are not convertible to eachother. That is what C# Standard says. Period.

So when you tried to reimplement bool and int compatibility you made a mistake. You use && which is logical operator, but in C# you can't override it and only &, which is implemented as bitwise. 1 & 2 == 0 == false! here it is!

You even should not overload bitwise ones, to maintain compatibility you just have to leave operator true and false.

This code works as you expect:

class Programx
{
    static void Main(string[] args)
    {
        MyInt a = 1, b = 2;
        bool res = a && b;
        Console.WriteLine("result is {0}", res);
    }

    class MyInt
    {
        public int val;
        public static bool operator true(MyInt t)
        {
            return t.val != 0;
        }
        public static bool operator false(MyInt t)
        {
            return t.val == 0;
        }
        public static implicit operator MyInt(int v)
        {
            return new MyInt() { val = v };
        }
        public static implicit operator bool(MyInt t)
        {
            return t.val != 0;
        }
    }
}

result is True

Your implementations of operator& and operator| are wrong. These binary operators have bitwise meanings when applied to integral types, and when applied to either Boolean types or classes that have their own & and | operators, they have logical AND and OR semantics (being the non-short-circuiting cousins of && and ||). Correct implementations would look as follows:

operator &(MyInt l, MyInt r) {return l.val != 0 && r.val != 0);}
operator |(MyInt l, MyInt r) {return l.val != 0 || r.val != 0);}

I'll try and make this simple, since I think people are overcomplicating this.

var x = 1 & 2;
// behind the scenes: 0001 AND 0010 = 0000
Console.Write(x); // 0, as shown above

Integers can NOT be used as booleans in C#. The result of:

if (1 && 2) // compile error
var x = 1 && 2; // compile error

There is no point to asking why an Integer can not be used as a boolean in C#, it just can't. The type system does not allow it. If one were to implement their own Integer class, they could provide implicit conversions from their type to bool, but int does not do this. You also have to make a choice when overloading; do you want bitwise behaviour, or logical behaviour. You can not have both.

Some languages allow 0, "", [] as 'falsey' values. C# does not. Get over it, and use a bool if you're doing boolean logic. If all else fails, Convert.ToBoolean on an int will return true for all non-zero values.

public static MyInt operator &(MyInt l, MyInt r) { return l.val & r.val; }

If I read the linked article correctly, res = a && b will be "expanded" to:

MyInt.false(a) ? a : MyInt.&(a, b)

MyInt.false(a) is false, so evaluates to:

MyInt.&(a, b)

which "expands" to:

a.val & b.val

which is (1 & 2) == 0, and thus false.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!