2009-12-10 17 views
15

私は、次のインターフェースにC#のインターフェイスでequals演算子==をオーバーライドするにはどうすればよいですか?

public interface IHaveAProblem 
{ 
    string Issue { get; set; } 
} 

を定義し、ここで私は、私は==の正しい結果を比較する得ることができますオブジェクトを使用する場合IHaveAProblem

public class SomeProblem : IHaveAProblem 
{ 
    public string Issue { get; set; } 

    public override bool Equals(object obj) 
    { 
     SomeProblem otherObj = obj as SomeProblem; 

     if (otherObj == null) 
     { 
      return false; 
     } 

     return this.Issue == otherObj.Issue; 
    } 

    public override int GetHashCode() 
    { 
     return base.GetHashCode(); 
    } 

    public static bool operator ==(SomeProblem rhs, SomeProblem lhs) 
    { 
     // Null check 
     if (Object.ReferenceEquals(rhs, null) || Object.ReferenceEquals(lhs, null)) 
     { 
      if (Object.ReferenceEquals(rhs, null) && Object.ReferenceEquals(lhs, null)) 
      { 
       // Both are null. They do equal each other 
       return true; 
      } 

      // Only 1 is null the other is not so they do not equal 
      return false; 
     } 

     return rhs.Equals(lhs); 
    } 

    public static bool operator !=(SomeProblem rhs, SomeProblem lhs) 
    { 
     // Null check 
     if (Object.ReferenceEquals(rhs, null) || Object.ReferenceEquals(lhs, null)) 
     { 
      if (Object.ReferenceEquals(rhs, null) && Object.ReferenceEquals(lhs, null)) 
      { 
       // Both are null. They do equal each other 
       return false; 
      } 

      // Only 1 is null the other is not so they do not equal 
      return true; 
     } 

     return !rhs.Equals(lhs); 
    } 
} 

の実装ですしています。私はそれがメモリをやっているのインターフェイスを比較しようとすると、

SomeProblem firstTest = new SomeProblem() 
    { 
     Issue = "Hello World" 
    }; 

SomeProblem secondTest = new SomeProblem() 
    { 
     Issue = "Hello World" 
    }; 

// This is true 
bool result = firstTest == secondTest; 

しかしSomeProblemに==演算子のではなく、比較

IHaveAProblem firstProblem = new SomeProblem() 
    { 
     Issue = "Hello World" 
    }; 

IHaveAProblem secondProblem = new SomeProblem() 
    { 
     Issue = "Hello World" 
    }; 

はそれが可能インターフェースがではなくSomeProblemに==を使用する必要がありですメモリを比較する?

私はfirstProblem.Equals(secondProblem)を実行して適切な結果を得ることができますが、フレームワークを作成していますが、最終的にどのように使用されるのかわかりません。私は==が正しく動作すると思った。

+1

ここではかなり徹底的な議論があります。作者は、あなたが共有していると思ういくつかの前提に関する電球の瞬間が少しあるようです:http://stackoverflow.com/questions/728434/operator-overloading-with-interface-based-programming-in-c –

答えて

22

オペレータ==は静的です。インターフェイスの静的メソッドをC#で定義することはできません。また、すべての演算子で、少なくとも1つの引数型が定義されているクラスと同じ型である必要があります。したがって、演算子のオーバーロードがインターフェイスにない:(

代わりに抽象クラスを使用する - およびC#演算子の[。その理由は、コメントを参照して、編集]

+1

おそらく私は間違った最後の段落を得るが、それは間違っていると思う。私は言う: "演算子の既定の実装(参照型とインターフェイス上)は、' Object'によって提供される 'ReferenceEquals'メソッドのように振る舞います。また、structにはデフォルトの演算子==はありませんが、あなたが定義することもできます。 – thaller

0

(静的メソッドが仮想できないので...)再び、オペレータは仮想ではないかもしれない

がオペレータを定義する静的およびオーバーライド静的ですメソッドは...面倒です。

継承されたEquals()メソッドを単純にオーバーライドしないのはなぜですかオブジェクト?これはかなり簡単で、静的メソッドをオーバーライドする必要はありません。

4

IIRC(と私はここで間違っている可能性があります)、C#インターフェイスはオペレータのオーバーロードを許可していません。

しかし、この場合は問題ありません。 ==演算子は通常、参照等価にマップされます。あなたが価値の平等を求めているように思えます。つまり、.Equals()(そして結果的に.GetHashCode())の機能を無効にしたいということです。あなたのインターフェイスはIEquatable()から継承されています。

0

IComparableを実装しようとしましたか?クラスの実装で

public interface IHaveAProblem : IComparable 
{ 
    string Issue { get; set; } 
} 

そして:あなたは2つのSomeProblemのインスタンスではなく、任意の他の実装を比較した場合にのみ、この作品、

public class SomeProblem : IHaveAProblem 
{ 
    public string Issue { get; set; } 

    ... 

    public int CompareTo(object obj) 
    { 
     return Issue.CompareTo(((SomeProblem)obj).Issue); 
    } 
} 

(注)このよう

IHaveAProblemインターフェイス

NullReferenceExceptionが発生する可能性があるかどうかは不明です。

2

これは古い質問ですが、すべての例では2つのクラスインスタンスを比較する方法が示されていますが、2つのインターフェイスインスタンスを比較する方法を指摘する人はいません。

場合によっては、これはインターフェイスを比較する最も早い方法です。

public interface IHaveAProblem 
{ 
    string Issue { get; set; } 
} 

public class IHaveAProblemComparer : IComparer<IHaveAProblem>, IEqualityComparer<IHaveAProblem> 
{ 
    public int Compare(IHaveAProblem x, IHaveAProblem y) 
    { 
     return string.Compare(x.Issue, y.Issue); 
    } 

    public bool Equals(IHaveAProblem x, IHaveAProblem y) 
    { 
     return string.Equals(x.Issue, y.Issue); 
    } 

    public int GetHashCode(IHaveAProblem obj) 
    { 
     return obj.GetHashCode(); 
    } 
} 

使用法?

IHaveAProblemComparer comparer = new IHaveAProblemComparer(); 

List<IHaveAProblem> myListOfInterfaces = GetSomeIHaveAProblemObjects(); 
myListOfInterfaces.Sort(comparer); // items ordered by Issue 

IHaveAProblem obj1 = new SomeProblemTypeA() { Issue = "Example1" }; 
IHaveAProblem obj2 = new SomeProblemTypeB() { Issue = "Example2" }; 

bool areEquals = comparer.Equals(obj1, obj2); // False 
関連する問題