8

コンテキストのコード:

class a
{

}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

  a a=null;
  b b=null;
  a = b;

  //compiler: cannot apply operator '==' to operands of type tralala...
  bool c = a == b; 

異なるタイプのインスタンスで==演算子を使用することは可能ですか?暗黙的に別のインスタンスに変換できますか?私は何を取りこぼしたか?

編集:
タイプが同じ呼び出し==でなければならない場合、なぜ

int a=1;
double b=1;
bool c=a==b; 

動作しますか?

4

5 に答える 5

17

implicitオペレーターは割り当てのためにのみ機能します。

次のように、equality(==)演算子をオーバーロードします。

class a
{
    public static bool operator ==(a x, b y)
    {
        return x == y.a;
    }

    public static bool operator !=(a x, b y)
    {
        return !(x == y);
    }
}

class b
{
    public a a{get;set;}
    public static implicit operator a(b b)
    {
        return b.a;
    }
}

これにより、投稿で提案されているタイプaの2つのオブジェクトを比較できるようになります。b

var x = new a();
var y = new b();
bool c = (x == y); // compiles

ノート:

GetHashCodeコンパイラが警告するように、単にandメソッドをオーバーライドすることをEqualsお勧めしますが、それらを抑制したいように思われるので、次のように行うことができます。

のクラス宣言を次のように変更aします。

#pragma warning disable 0660, 0661
class a
#pragma warning restore 0660, 0661
{
    // ...
}
于 2009-05-21T09:26:57.593 に答える
12

異なるタイプのインスタンスで==演算子を使用することは可能ですか?暗黙的に別のインスタンスに変換できますか?

はい。

私は何を取りこぼしたか?

これが仕様の関連部分です。ハイライトされた単語を見逃しました。

事前定義された参照型の等価演算子では、両方のオペランドが参照型の値またはリテラルnullである必要があります。さらに、 一方のオペランドの型からもう一方のオペランドの型への標準的な暗黙の変換が存在します。

ユーザー定義の変換は、定義上、標準の変換ではありません。これらは参照型です。したがって、事前定義された参照型の等価演算子は候補ではありません。

タイプが同じ呼び出し==でなければならない場合、なぜ[double == int]が機能するのですか?

タイプは同じでなければならないというあなたの仮定は正しくありません。intからdoubleへの標準的な暗黙の変換があり、2つのdoubleを取る等式演算子があるため、これは機能します。

私はあなたもこのビットを逃したと思います:

事前定義された参照型の等価演算子を使用して、コンパイル時に異なることがわかっている2つの参照を比較することは、コンパイル時のエラーです。たとえば、オペランドのコンパイル時の型が2つのクラス型AとBであり、AとBのどちらも他方から派生していない場合、2つのオペランドが同じオブジェクトを参照することは不可能です。したがって、この操作はコンパイル時エラーと見なされます。

于 2009-05-21T15:37:42.760 に答える
1

興味のある型の==演算子を実際にオーバーライドする必要があると思います。型が暗黙的に変換可能であっても、コンパイル/ランタイムが文句を言うかどうかは、実験する必要があります。

public static bool operator ==(a a, b b)
    {
        //Need this check or we can't do obj == null in our Equals implementation
        if (((Object)a) == null)
        {
            return false;
        }
        else
        {
            return a.Equals(b);
        }
    }

または、ole6kaが提案するようなEquals実装を使用して、実装が必要な型キャストを実行することを確認します。

于 2009-05-21T09:27:06.017 に答える
0

http://msdn.microsoft.com/en-us/library/8edha89s.aspx

いずれの場合も、1つのパラメーターは、演算子を宣言するクラスまたは構造体と同じタイプである必要があります(...)

于 2009-05-21T09:24:05.837 に答える
-1

これを使って

 bool c = a.Equals(b);
于 2009-05-21T09:23:00.737 に答える