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; }
}
}
}
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
.
来源:https://stackoverflow.com/questions/5203770/why-is-1-2-in-c-sharp-false