2011-12-07 22 views
1

暗黙の演算子が存在していても、オブジェクト型とオブジェクト型の比較ではなく、等価比較のためにC#で暗黙的にオブジェクトをint型に変換できるのはなぜですか?なぜ等価チェックは、オブジェクト型の暗黙的な変換を許可しませんが、intのですか?

bool errorHere = valueOnly == valuePair;行が例外を示しています。ここで

class Program 
{ 
    static void Main(string[] args) 
    { 
     ValueOnly valueOnly = new ValueOnly(); 
     ValuePair valuePair = new ValuePair(); 
     bool areEqual = valueOnly.Value == valuePair; 
     bool errorHere = valueOnly == valuePair; 
     bool butNotHere = valueOnly == (ValueOnly)valuePair; 
     valueOnly = valuePair; // Or Here 
    } 
} 

public class ValuePair 
{ 
    public int Value { get; set; } 
    public string Text { get; set; } 

    public static implicit operator ValueOnly(ValuePair valuePair) { 
     if (valuePair.Text != null || valuePair.Value != 0) { 
      return new ValueOnly() { Value = valuePair.Value }; 
     } 
     return null; 
    } 

    public static implicit operator int(ValuePair valuePair) { 
     return valuePair.Value; 
    } 
} 

public class ValueOnly 
{ 
    public int Value { get; set; } 
} 

は誤りです:

Error Operator '==' cannot be applied to operands of type 'ValueOnly' and 'ValuePair' 

答えて

1

C#が最も確かに、任意の目的のためにint sのオブジェクトの暗黙の変換を許可していません。あなたがラインを参照しているかどうか分かりません。このような変換を「許可」しているかどうかわかりません。

bool butNotHere = valueOnly == (ValueOnly)valuePair; 

もしそうなら、そんなことはしません。 (コードを正しく読み込むと、値がデフォルト構成の整数になるのでnullが返されます)falseと評価される2つのオブジェクト間の参照の比較を行います(nullは参照ではありません)何かに等しい)。

暗黙の変換演算子を定義すると、C#は必要なときにいつでも使用します。したがって、私はあなたの質問が、他のものよりも、その引数のタイプに基づいて、等価演算子がどのように動作するかを理解することで、より多くのことを行う必要があると思います。

更新、valueOnly == valuePairチェックについて:

C#の仕様は、7.10.6(参照型等価演算子が)状態:

It is a binding-time error to use the predefined reference type equality operators to compare two references that are known to be different at binding-time. For example, if the binding-time types of the operands are two class types A and B, and if neither A nor B derives from the other, then it would be impossible for the two operands to reference the same object. Thus, the operation is considered a binding-time error.

あなたはクラスのオブジェクトを比較することができるようにしたい場合タイプが等しいかどうかを確認するには、IEquatable<T>インターフェイスを実装し、IEquatable<T>.Equalsで実装するようにobject.Equalsをオーバーライドする必要があります(つまり、object.GetHashCodeをオーバーライドする必要があります)。

しかし、アイテムを比較するときに「隠された」コンバージョンに頼るのは悪い考えです。無関係のクラスを比較することを話しているなら、できるだけ顕著な比較を行うことで、多くの悩みを解消します。そのために、私はあなたがValuePairクラスにこれを追加する必要がvalueOnly == valuePairを許可するに

if(valuePair.Value == valueOnly.Value) 
+0

私はそれが間違っていると言っているかもしれませんが、もしそうなら、なぜこれが機能しますか? "bool areEqual = valueOnly.Value == valuePair;" valueOnlyのValueプロパティはintで、valuePairは暗黙的にint型に変換されます。 – Daryl

+0

参照している行は、明示的な変換を実行しており、定義済みの暗黙の演算子を使用しています。本当の質問は、どうして明示的に変換を定義する必要があるのでしょうか? – Daryl

+1

@ダリル:あなたの質問をもう一度読んだ後で改訂しました。二つの型は無関係であるため、 'ValuePair'から' ValueOnly'への変換を明示的に定義しなければなりません。 – Jon

0

をローテクを示唆している:

public static bool operator == (ValueOnly valueOnly, ValuePair valuePair){ 
    ValueOnly value = valuePair; 
    return valueOnly.Value == value.Value; 
} 

をこれは、暗黙の型変換を使用し、次に実行します(私はValueOnlyクラスの等価演算子を提供していないので)私が...そして今、私はそれを考えること

探してい平等のチェックは、暗黙の型変換は馬鹿です:

public static bool operator == (ValueOnly valueOnly, ValuePair valuePair){ 
    return valueOnly.Value == valuePair.Value; 
} 
関連する問題