14

私は他の質問に不満を感じました。だから私はこの例を書きました。

Cでは、以下が当てはまります。デモを見る

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

出力:

1

C#で。FALSEです。なぜこれが間違っているのですか?また、この例で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; }
        }
    }
}
4

4 に答える 4

22

Cありませboolん。慣例はそれ0falseあり、!= 0ありtrueます。ifステートメントは、条件式の結果を正確にそのように扱います。

C++ bool紹介されました。しかし、それは古い規則と互換性があり、ととして0扱われ、 と の間に暗黙の変換がありました。falsefalse0intbool

C# では同じ方法ではありません。 and がboolありint、それらは相互に変換できません。それがC#標準の言うことです。限目。

boolしたがって、再実装とint互換性を試みたとき、あなたは間違いを犯しました。論理演算子である && を使用しますが、C# ではそれをオーバーライドすることはできず、ビットごとに実装される & のみです。1 & 2 == 0 == false! ここにあります!

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

結果は真です

于 2011-03-05T12:24:06.400 に答える
9

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);}
于 2011-03-05T12:26:51.280 に答える
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クラスを実装する場合、型からboolへの暗黙的な変換を提供できますが、intはこれを行いませ。また、オーバーロードするときに選択する必要があります。ビット単位の動作、または論理的な動作が必要ですか。両方を持つことはできません。

一部の言語では、「falsey」値として0、 ""、[]を使用できます。C#はそうではありません。それを乗り越えて、ブール論理を実行している場合はブールを使用してください。他のすべてが失敗しConvert.ToBooleanた場合、intはtrueゼロ以外のすべての値を返します。

于 2011-03-05T12:55:07.277 に答える
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.

于 2011-03-05T12:32:14.043 に答える