为什么1&& 2在C#中假?

时间:2011-03-05 12:20:21

标签: c# boolean boolean-operations

I got frustated with my other question。所以我写了这个例子。

In C the below is true. See demo

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

输出:

1

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

BTW下面描述了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; }
        }
    }
}

4 个答案:

答案 0 :(得分:22)

C中没有bool。惯例是0false!= 0trueif语句完全按照这种方式处理条件表达式结果。

引入了C++ bool。但它与旧规则兼容,0被视为falsefalse视为0intbool之间存在隐式转换

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

因此,当您尝试重新实现boolint兼容性时,您犯了一个错误。你使用&&这是逻辑运算符,但在C#中你不能覆盖它,只能&amp ;,它是按位实现的。 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;
        }
    }
}

结果为真

答案 1 :(得分:9)

您对运营商和运营商的实施和操作员|错了。当应用于整数类型时,这些二元运算符具有逐位含义,并且当应用于具有它们自己的&的布尔类型或类时。和|运算符,它们具有逻辑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);}

答案 2 :(得分:2)

我会尝试这么简单,因为我认为人们过于复杂了。

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

答案 3 :(得分:1)

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