2009-05-21 21 views
4

コンテキストのためのいくつかのコード:C#の暗黙の変換と==演算子

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; 

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

編集:
種類が同じ呼び出し==、なぜ

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

作品でなければなりませんか?

+1

値型で参照型ではないため、int/doubleの例が動作すると仮定します... –

+1

これは理由があります。問題がある場合は、参照型が値型と同様に暗黙的に変換を実行できない理由を説明しません。 –

答えて

12

implicit演算子は代入にのみ使用できます。

次のような等式(==)演算子をオーバーロードしたい:

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

これは、あなたの記事で示唆したように、あなたがタイプabの2つのオブジェクトを比較できるようにする必要があります。

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

注:

コンパイラは警告しているように私は、単にGetHashCodeEqualsメソッドをオーバーライドrecommmend、しかし、あなたがそれらをSUPRESSしたいように見えるとして、次のように、あなたはそれを行うことができます。

変更にaのあなたのクラス宣言:

#pragma warning disable 0660, 0661 
class a 
#pragma warning restore 0660, 0661 
{ 
    // ... 
} 
+0

この場合、a == b式は問題なくコンパイルされます。 – Galilyou

+0

これは正解のようです。これも分かりました。のみ - 私は演算子のオーバーロードは、この場合(それはgethash()とequals()関数のオーバーロードも必要とします)過度なことだと思います。 –

+0

ええ、ユーザー定義型に対してカスタム(オーバーロードされた)演算子を定義または使用することには制限がありません。 – Noldorin

0

は、それぞれの場合において、この

bool c = a.Equals(b); 
+0

これは特別な場合には役に立ちません。lambdaとbuilderパターンを悪用して、次のような動的プロパティ設定ツールを作成しているためです。factory.Object.With(object => object.MyProp == newPropValue).Create() –

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実装を使用し、必要な型キャストを実装するようにしてください。

9

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

はい。

私は何を欠場しましたか?

ここでは、仕様の関連部分を示します。あなたはハイライトされた単語を逃しました。

演算子は両方のオペランド 【こと】必要とする予め定められた基準のタイプの等価は、参照型の値または リテラルヌルです。さらに、標準 いずれかのオペランドの タイプから他のオペランドのタイプ への暗黙的な変換が存在します。

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

種類が同じである必要がある場合は、==、 となります。なぜ[double == int]が機能するのですか?

タイプが同じでなければならないという想定は間違っています。 intからdoubleへの標準的な暗黙の変換があり、2つのdoubleを取る等価演算子があるので、これは機能します。

私はあなたにも、このビットを逃したと思う:

、コンパイル時に異なることが知られている2つの参照 を比較する オペレーター 事前に定義された参照型の平等を使用するようにコンパイル時エラーとします時間。例えば、オペランドの コンパイル時の型は 2つのクラスタイプA及びBである場合、及び AもBも、他の 由来する場合、それは同じ を参照する 二つのオペランドのために不可能ですオブジェクト。したがって、操作はコンパイル時エラーとみなされます です。

+0

これをクリアしていただきありがとうございます。 –

関連する問題