2017-06-07 61 views
2

我使用overriden 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?

+1

'MyClass'應該重寫'GetHashCode',因爲它覆蓋'Equals'。甚至有一個編譯器警告它。 – Dirk

+0

你也應該像這樣覆蓋'GetHashCode'方法:https://stackoverflow.com/a/38434457/2946329 –

+0

所有的set方法都需要'GetHashCode'(在使用'Equals'之前)。但總的來說,你應該總是實現'GetHashCode' **和**'Equals'在一起 –

回答

1

您需要在MyClass中實現IEquatable<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

您必須覆蓋GetHashCode還有:

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

Distinct第一的哈希碼,應該計算比實際Equals更快的進行比較。 Equals僅在兩個實例的哈希碼爲等於時才被進一步消除。

3

docsDistinct:從序列

返回不同元件通過使用默認的相等比較對值進行比較。

讓我們來看看what the default equality comparer does:T型

Default屬性檢查是否實現了System.IEquatable<T>接口,如果是這樣,將返回使用該實現的EqualityComparer<T>。否則,它將返回一個EqualityComparer<T>,該EqualityComparer<T>使用由T提供的替代Object.EqualsObject.GetHashCode

所以基本上,使這項工作,您:

  • 實施GetHashCode以及
  • 實施IEquatable<T>
  • 呼叫的Distinct接受的自定義相等比較器過載。

如果我是你,我會選擇第二個,因爲你需要改變你的代碼最少。

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