2017-06-07 2 views
2

オーバーライドされたEqualsでクラスを作成しました。問題は、私のクラスでDistinctメソッドが動作しないことです。オーバーライドされたEqualsのクラスでは、別のメソッドが機能しません。

class MyClass 
{ 
    public int Item1 { get; private set; } 
    public int Item2 { get; private set; } 

    public MyClass(int item1, int item2)=>(Item1,Item2)=(item1,item2); 


    public override bool Equals(object obj) 
    { 
     var other = obj as MyClass; 

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

     return (this.Item1 == other.Item1 && this.Item2 == other.Item2); 
    } 
} 

class Program 
{ 
    static void Main(string[] args) 
    { 
     MyClass x = new MyClass(1, 0); 
     MyClass y = new MyClass(1, 0); 
     var list = new List<MyClass>(); 
     list.Add(x); 
     list.Add(y); 


     bool b = x.Equals(y)); //True 
     var distincts = list.Distinct(); //Doesn't work, contains both 
    } 
} 

どうすれば修正できますか、それではEquals in Distinctを使用しないのですか?あなたにもGetHashCodeをオーバーライドする必要が

+1

'MyClass'は' Equals'をオーバーライドするので 'GetHashCode'もオーバーライドする必要があります。コンパイラの警告もあります。 – Dirk

+0

また、次のように 'GetHashCode'メソッドをオーバーライドする必要があります:https://stackoverflow.com/a/38434457/2946329 –

+0

' GetHashCode'( 'Equals'が使用される前)はすべての設定メソッドに必要です。しかし、一般的には、常に 'GetHashCode' **と** Equals'を実装してください。 –

答えて

1

IEquatable<MyClass>MyClassに実装し、GetHashCodeEqualsメソッドの独自の実装を提供する必要があります。

詳細については、thisを参照してください。

class MyClass 
{ 
    public int Item1 { get; private set; } 
    public int Item2 { get; private set; } 

    public MyClass(int item1, int item2)=>(Item1,Item2)=(item1,item2); 


    public override bool Equals(object obj) 
    { 
     var other = obj as MyClass; 

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

     return (this.Item1 == other.Item1 && this.Item2 == other.Item2); 
    } 

    public override int GetHashCode() 
    { 

     return this.Item1; 
    } 
} 
2

public override int GetHashCode() 
{ 
    return Item1; // or something 
} 

Distinctは、最初に、実際のEqualsよりも高速に計算する必要があるハッシュコードを比較します。 Equalsは、ハッシュコードがと等しい場合、2つのインスタンスに対してである場合にのみさらに詳細に把握されます。

3

Distinctdocs

値を比較するために既定の等値比較を使用することにより、シーケンスから一意の要素を返します。

はのはwhat the default equality comparer doesを見てみましょう:

Defaultプロパティ検査タイプTはSystem.IEquatable<T>インタフェースを実装し、もしそうなら、その実装を使用EqualityComparer<T>を返すかどうか。それ以外の場合は、 Object.EqualsObject.GetHashCodeのTで指定されたオーバーライドを使用するEqualityComparer<T>を返します。

だから、基本的には、この作品を作るために、あなたのいずれか:

  • 同様
  • GetHashCodeを実装
  • IEquatable<T>
  • を実装するカスタム等値比較子を受け入れるDistinctのオーバーロードを呼び出します。

私があなただったら、コードの最小限の部分を変更する必要があるため、2番目のものを選択します。

class MyClass: IEquatable<MyClass> { 
    ... 

    public bool Equals(MyClass obj) 
    { 
     if (obj == null) 
     { 
      return false; 
     } 

     return (this.Item1 == obj.Item1 && this.Item2 == obj.Item2); 
    } 
} 
+0

は私にとってはうまくいきませんでした – Dork

関連する問題