为什么C#中的1 && 2是假的?

我对另一个问题感到沮丧 。 所以我写了这个例子。

在C中,以下是真实的。 见演示

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

输出:

 1 

在C#中。 这是假的。 为什么这是假的? 此外,我不明白为什么我需要在这个例子中创建bool运算符,但不是在我的另一个问题,但无论如何。 为什么以下是假的? 对我来说完全是无稽之谈。

这里描述了使得下面的假的逻辑

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

C中没有bool 。 惯例是0false!= 0trueif语句处理条件表达式结果完全相同。

C++中引入了bool 。 但它与旧规则兼容, 0falsefalse0 ,并且intbool之间存在隐式转换。

在C#中它的方式不一样:有boolint ,它们不能互相转换。 这就是C#标准所说的。 期。

因此,当您尝试重新实现boolint兼容性时,您犯了一个错误。 你使用&&这是逻辑运算符,但是在C#中你不能覆盖它而只能覆盖&,它是按位实现的。 1 & 2 == 0 == false ! 这里是!

你甚至不应该按比例重载,为了保持兼容性,你只需要将operator truefalse

此代码按预期工作:

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

结果是真的

您的operator&和operator的实现 错了。 当应用于整数类型时,这些二元运算符具有逐位含义并且当应用于具有自己的&和|的布尔类型或类时。 运算符,它们具有逻辑AND和OR语义(是&&和||的非短路表兄弟)。 正确的实现看起来如下:

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

我会尽量简单,因为我认为人们过于复杂。

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

整数不能在C#中用作布尔值。 的结果:

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

没有必要问为什么在C#中不能将Integer用作布尔值,它只是不能。 类型系统不允许它。 如果要实现自己的Integer类,他们可以提供从类型到bool的隐式转换,但是int不会这样做。 您还必须在超载时做出选择; 你想要按位行为或逻辑行为吗? 你不能兼得。

有些语言允许0,“”,[]为’falsey’值。 C#没有。 克服它,如果你正在做布尔逻辑,那就使用bool。 如果所有其他方法都失败,则int上的Convert.ToBoolean将对所有非零值返回true

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

如果我正确阅读了链接文章,res = a && b将“扩展”为:

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

MyInt.false(a)为false,因此评估为:

 MyInt.&(a, b) 

其中“扩展”为:

 a.val & b.val 

这是(1&2)== 0,因此是false