2012-08-09 58 views
12

我有以下的LINQ表達式:鮮明的()不工作

AgentsFilter = new BindableCollection<NameValueGuid>((
    from firstEntry in FirstEntries 
    select new NameValueGuid { 
     Name = firstEntry.Agent, 
     Value = firstEntry.AgentId 
    }).Distinct() 
); 

因爲某種原因只是,AgentsFilter Collection是充滿重複的。我的Distinct()有什麼問題?

回答

28

Distinct將使用Equals方法NameValueGuid找到重複項。如果您不覆蓋Equals,那麼它將檢查參考。

您可以通過使用匿名類型來添加額外步驟以避免重寫Equals。匿名類型自動覆蓋Equals和GetHashCode來比較每個成員。做匿名類型的獨特,然後投影到你的班級將解決問題。

from firstEntry in FirstEntries 
select new 
{ 
    Name = firstEntry.Agent, 
    Value = firstEntry.AgentId 
}).Distinct().Select(x => new NameValueGuid 
{ 
    Name = x.Name, 
    Value = x.Value 
}); 
+0

謝謝你和所有其他人回答。 – 2012-08-09 13:36:28

+1

投票贊成'不同意將使用Equals方法來查找重複。如果你不覆蓋等於,那麼它將檢查參考'。 – 2014-11-14 13:49:00

7

您可能沒有提供對NameValueGuidGetHashCodeEquals的實現。

或者,如果這不可行,您可以將IEqualityComparer<NameValueGuid>的實例傳遞給Distinct的調用。

參見:http://msdn.microsoft.com/en-us/library/system.linq.enumerable.distinct.aspx

+0

很好的解釋,但有另一種解決方案:使用匿名類型(請參閱* Cadrell0 *的答案) – 2012-08-09 13:25:31

+0

+1,沒有意識到我需要覆蓋'GetHashCode'以及'Distinct'工作。覆蓋它之後,似乎'Distinct'首先調用'GetHashCode'來確定它是否需要調用'Equals'。 – DCShannon 2015-02-11 22:49:59

4

您需要定義什麼Distinct是指一類具有NameValue性質的上下文。請參閱MSDN

嘗試讓您提供比較器的Distinct的重載。

例如:

AgentsFilter = new BindableCollection<NameValueGuid>((from firstEntry in FirstEntries 
    select new NameValueGuid 
    { 
     Name = firstEntry.Agent, 
     Value = firstEntry.AgentId 
    }) 
    .Distinct((nvg) => nvg.Value) 
); 

或者,如果你有機會到NameValueGuid的代碼定義,那麼您可以覆蓋GetHashCodeEquals適當的類。再次看到MSDN

4
select new 
{ 
    Name = firstEntry.Agent, 
    Value = firstEntry.AgentId 
}) 
.Distinct() 
.Select(x => new NameValueGuid 
{ 
    Name = x.Name, 
    Value = x.Value 
});