簡體   English   中英

Linq除了忽略自定義比較器?

[英]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這意味着項目xy 可能相同,因此需要調用Equals

但是,不建議這樣做,因為在GetHashCode中僅返回0會導致性能問題。

最好的選擇是使用內置的StringComparer.OrdinalIgnoreCase相等比較器。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM