[英]Linq Except ignoring Custom comparer?
在此玩具代碼中:
void Main()
{
var x = new string[] {"abc", "DEF"};
var y = new string[] {"ABC", "def"};
var c = new CompareCI();
var z = x.Except(y, c);
foreach (var s in z) Console.WriteLine(s);
}
private class CompareCI : IEqualityComparer<string>
{
public bool Equals(string x, string y)
{
return string.Equals(x, y, StringComparison.OrdinalIgnoreCase);
}
public int GetHashCode(string obj)
{
return obj.GetHashCode();
}
}
似乎Except方法正在忽略我的客戶比較器。 我得到以下結果:
abc
DEF
看起來這種情況並沒有被忽略。 另外,當我在調試下運行它並在對string的調用處放置一個斷點時,在客戶比較器中等於斷點,盡管代碼已運行並且得到了發布的結果,但斷點從未命中。 我期望沒有結果,因為如果忽略大小寫,則序列是相等的。
猜猜我做錯了什么,但是我需要第二雙眼睛才能發現它。
調試代碼顯示,調用了GetHashCode(),但未調用Equals()。
我認為這是因為兩個相等的對象必須具有相等的哈希碼,並從Equals()返回true。 如果哈希碼不同,則它們不能相等,因此無需運行Equals()函數。
如果哈希函數不區分大小寫,即obj.ToUpper()。GetHashCode(),則您的代碼將起作用。
.NET Framework已經提供了StringComparer類 , 該類使用特定的大小寫和基於區域性的或有序的比較規則-因此,在這種情況下,無需創建自定義比較器。
這將起作用:
var x = new string[] { "abc", "DEF" };
var y = new string[] { "ABC", "def" };
var z = x.Except(y, StringComparer.OrdinalIgnoreCase);
Rui Jarimba的建議使用StringComparer.OriginalIgnoreCase起作用。
修改比較器:
public int GetHashCode(string obj)
{
return 0;
}
現在所有項目將具有相同的哈希值: 0
這意味着項目x
和y
可能相同,因此需要調用Equals
。
但是,不建議這樣做,因為在GetHashCode中僅返回0會導致性能問題。
最好的選擇是使用內置的StringComparer.OrdinalIgnoreCase
相等比較器。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.