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

发布于 2024-10-20 19:59:29 字数 1528 浏览 9 评论 0原文

我对我的其他问题感到沮丧。所以我写了这个例子。

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

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

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

旧时模样 2024-10-27 19:59:29

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

C++中引入了bool。但兼容旧规则,0视为falsefalse视为0,并且存在隐式转换介于 intbool 之间。

在 C# 中则不然:有 boolint 并且它们不能相互转换。这就是 C# 标准所说的。时期。

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

您甚至不应该重载按位运算符,为了保持兼容性,您只需保留运算符 true 和 false 即可。

此代码按您的预期工作:

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

结果为 True

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

执手闯天涯 2024-10-27 19:59:29

您的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);}

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);}
凉宸 2024-10-27 19:59:29

我会尝试让这个变得简单,因为我认为人们把这个复杂化了。

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

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

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

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.

冬天旳寂寞 2024-10-27 19:59:29
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)

which“扩展”为:

a.val & b.val

which is (1 & 2) == 0,因此 false

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文