Why is 1 && 2 in C# false?

I got frustated with my other question. So i wrote up this example.

In C the below is true. See demo

int main()
{
printf("%d", 1 && 2);
return 0;
}

Output:

1

In C#. It is FALSE. WHY is this false? Also i dont understand why i needed to create the bool operator in this example but not the one in my other question but no matter. Why is the below false? it makes no sense to me.

BTW the logic making the below false is described here

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        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 MyInt operator &(MyInt l, MyInt r) { return l.val & r.val; }
            public static MyInt operator |(MyInt l, MyInt r) { return l.val | r.val; }
            public static implicit operator MyInt(int v) { return new MyInt() { val = v }; }
            public static implicit operator bool(MyInt t) { return t.val != 0; }
        }
    }
}

Answers


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.


Need Your Help

make WKWebview "real" fullscreen on iPhone X (remove safe area from WKWebView

ios wkwebview iphone-x

I'm trying to implement a "real" fullscreen in App WebView, meaning I want the webcontent to fully go under the notch no matter what.