2012-10-16 31 views
2

我寫了下面的代碼來實現在可能的最基本的方式Linq.Distinct(IEqualityComparer)顯着,但是simpleCollection回報2項,而是如果1實施中的LINQ C#

奇怪的是,我已經注意到,在Equals斷點永遠不會命中。

難道這與我執行GetHashCode()有關嗎?

public class testobjx 
    { 
     public int i { get; set; } 
    } 

    public class mytest 
    { 
     public Main() 
     { 
      var simpleCollection = new[] { new testobjx() { i = 1 }, new testobjx() { i = 1 } }.Distinct(new DistinctCodeType()); 
      var itemCount = simpleCollection.Count();//this should return 1 not 2. 
     } 
    } 

    public class DistinctCodeType : IEqualityComparer<testobjx> 
    { 
     public bool Equals(testobjx x, testobjx y) 
     { 
      return x.i == y.i; 
     } 

     public int GetHashCode(testobjx obj) 
     { 
      return obj.GetHashCode(); 
     } 
    } 
+0

如果x,y或obj爲空,該怎麼辦? – n8wrl

+0

如果GetHashCode的結果不匹配,則甚至不檢查Equals。處理你的GetHashCode實現。 –

+1

供參考:http://msmvps.com/blogs/jon_skeet/archive/2010/12/30/reimplementing-linq-to-objects-part-14-distinct.aspx –

回答

5

嘗試:

public int GetHashCode(testobjx obj) 
{ 
    if (obj == null) return 0; 
    return obj.i.GetHashCode(); 
} 
+1

如果不是隻包含一個整數「i」的類,它包含10個獨立的整數或任何其他數量的複雜屬性,那麼該怎麼辦? – maxp

+0

@maxp,看看這個答案http://stackoverflow.com/a/263416/1009661。像ReSharper這樣的VS插件也能夠生成一些通用接口和方法的實現,包括GetHashCode。 – 2kay

1

的GetHashCode對於對象的默認實現是基於對象的實例,使具有相同值testobjx的兩個實例有不同的散列碼。你需要修改你的GetHashCode方法來詢問對象的屬性。如果對象具有多個屬性,則需要確定哪些對象唯一標識對象並從中組合一個散列碼。

+0

GetHashCode的默認實現不能唯一標識一個對象。它不能。它有40億個可能的價值,並且最可靠的是有超過40億個可能的對象。但即便如此,在開始接近40億之前,您將開始獲得[哈希碼相互衝突](http://blogs.msdn.com/b/ericlippert/archive/2010/03/22/socks-birthdays-and -hash-collisions.aspx)。小心使用GetHashCode關聯唯一性。這不是它的意圖。它有助於平衡散列表。它縮小了事情的範圍。但是一個合理的實現永遠不會保證唯一性。 –