3

「==演算子が定義されていない」場合はどうなりますか?

例:

class a
{
    int variable = 0;
}
class b
{
    void proc()
    {
        a ref1 = new a();
        a ref2 = new a();
        bool cmp1 = ref1 == ref2;//?
        bool cmp2 = ref1 == ref1;//?
    }
}

構造体を扱うときは違いますか?

マーシャリングされた ( System.Runtime.Remoting.*) オブジェクト (シングルトン) はどうですか?

4

4 に答える 4

4

ユーザー定義の値型の場合、コードはコンパイルされません。

具体的には、次のエラーでコンパイルに失敗します:「演算子'=='はタイプ'a'および'a'のオペランドに適用できません」。

「==および!=演算子は、構造体が明示的にオーバーロードしない限り、構造体を操作できません。」

両方をオーバーロードする必要があります。「...構造体の場合、Object.Equals(Object)(System.ValueTypeのオーバーライドされたバージョン)のデフォルトの実装は、次を使用して値の同等性チェックを実行するためEquals()、メソッドで デフォルトを使用することはおそらく望ましくありません。タイプ内のすべてのフィールドの値を比較するためのリフレクション。実装者が構造体の仮想Equalsメソッドをオーバーライドする場合、目的は、値の同等性チェックを実行するより効率的な手段を提供し、オプションで、構造体のフィールドまたはプロパティ。」

ユーザー定義の参照型の場合(OPの例のように簡略化された場合):

「==および!=演算子は、クラスがオーバーロードしなくてもクラスで使用できます。ただし、デフォルトの動作では、参照の等価性チェックが実行されます。クラスでは、Equalsメソッドをオーバーロードする場合は、 ==および!=演算子ですが、必須ではありません。」

演算子をオーバーロードしない場合、おそらく参照等価性テストのみが行われます。

演算子のオーバーロード解決により、デフォルトの代わりに別の実装が選択される可能性があるため、「簡略化されたケース」。

//Minimal example, for demonstration only.
//No Equals(), GetHaschode() overload, no IEquatable<T>, null checks, etc..
class Program
{
    static void Main()
    {

        MyMoreDerived a = new MyMoreDerived() { fbase = 1, fderived = 3 };
        MyMoreDerived b = new MyMoreDerived() { fbase = 2, fderived = 3 };

        //Even though MyMoreDerived does not overload the operators, this
        //will succeed - the definition in MyDerived will be used.
        if (a == b)
        {
            //Reached, because the operator in MyDerived is used.
            Console.WriteLine("MyDerived operator used: a == b");
        }

        a.fderived = 2;
        b.fbase = 1;
        //a => {1, 2} 
        //b => {1, 3}
        //Since 2 != 3, the operator in MyDerived would return false.
        //However only the operator in MyBase will be used.
        if ((MyBase)a == (MyBase)b)
        {
            //Reached, because the operator in MyBase is used.
            Console.WriteLine("MyBase operator used: a == b");
        }

        b.fderived = 2;
        //a => {1, 2} 
        //b => {1, 2}
        //Now both operator definitions would compare equal,
        //however they are not used.
        if ((object)a != (object)b)
        {
            //Reached, because the default implementation is used
            //and the references are not equal.
            Console.WriteLine("Default operator used: a != b");
        }

    }

    class MyBase
    {
        public int fbase;

        public static bool operator ==(MyBase x, MyBase y)
        {
            return x.fbase == y.fbase;
        }

        public static bool operator !=(MyBase x, MyBase y)
        {
            return x.fbase != y.fbase;
        }

    }

    class MyDerived : MyBase
    {
        public int fderived;

        public static bool operator ==(MyDerived x, MyDerived y)
        {
            return x.fderived == y.fderived;
        }

        public static bool operator !=(MyDerived x, MyDerived y)
        {
            return x.fderived != y.fderived;
        }

    }

    class MyMoreDerived : MyDerived
    {
    }

}

シングルトンは、参照型のコンテキストで最も意味があり、その目的は1つの特定のインスタンスを返すことです。参照が同じであるが、オブジェクトがそれ自体と「等しくない」という合理的なケースを想像することはできません。

リモーティングを使用する場合でも、運用コントラクトをデータコントラクトから分離することをお勧めします。前者は通常MarshalByRefObject、サーバー側のsによって実装されます(インターフェイスによって定義された操作を実装します)。後者は、値によってマーシャリングされ、クライアントとサーバーによって共有される可能性のあるデータ/メッセージクラスを使用します。データクラスの演算子をオーバーロードする場合は、大きな問題にはならない可能性があります。ただし、これらはリモートオブジェクトを参照/呼び出すべきではないと私は信じています。

==オペレーターをオーバーロードするカスタムクライアントプロキシを提供する場合でも、リモート呼び出しとオペレーターを隠すことは非常に悪い習慣であり、デバッグの悪夢!=です。(私があなたの意図を理解しているなら、それは私にはわかりません。)

于 2010-03-20T14:12:39.683 に答える
1

ポインター「a」と「b」がメモリ内の同じオブジェクトを指しているかどうかを比較する可能性があります。

これらのオブジェクトのフィールドを比較する必要がある場合は、比較関数を定義する必要があります。

IComparable インターフェイスから継承し、CompareTo メソッドを定義する必要があります。

ここを見てください: IComparable インターフェイス

于 2010-03-20T13:48:37.113 に答える
1

MSDN から:

定義済みの値の型の場合、等価演算子 (==) は、オペランドの値が等しい場合は true を返し、そうでない場合は false を返します。文字列以外の参照型の場合、2 つのオペランドが同じオブジェクトを参照している場合、== は true を返します。文字列型の場合、== は文字列の値を比較します。

于 2010-03-20T13:50:01.510 に答える
1

== がオーバーライドされていない場合、参照を比較して、それらが同じオブジェクトであるかどうかを確認していると思います。

例:

MyClass a = new MyClass(1);
MyClass b = new MyClass(1);
MyClass c = a;

if (a == b) // false
    ...
if (a == c) // true
    ...

したがって、上記のコードでは、cmp1 は false になりますが、cmp2 は true になります。

ただし、ユーザー定義の値の型の場合は、その型の実際の値を比較します。

于 2010-03-20T13:51:14.600 に答える