SortedSet<string> Linq .Except with Comparer 奇怪

SortedSet<string> Linq .Except with Comparer strangeness

我正在使用 .NET 4.6,我遇到了严重的陌生问题。我正在尝试从排序集中获取所有值的 IEnumerable,这些值不是传入的 IEnumerable 的不区分大小写的等价物。据我了解,这是 Except 的工作。

我有一个 class,CaseInsensitiveComparer 是这样实现的:

public class CaseInsensitiveComparer : IComparer<string>, IEqualityComparer<string>
{
    public static CaseInsensitiveComparer Instance { get; private set; }
    static CaseInsensitiveComparer()
    {
        Instance = new CaseInsensitiveComparer();
    }

    public int Compare(string a, string b)
    {
        var ret = string.Compare(a, b, true);
        return ret;
    }

    public bool Equals(string a, string b)
    {
        return Compare(a, b) == 0;
    }

    public int GetHashCode(string a)
    {
        return a.GetHashCode();
    }
}

我是这样使用的:

    public void DotNetWeirdness()
    {
        var a = new SortedSet<string>();
        a.Add("A");
        var b = a.Except(new string[] { "a" }, CaseInsensitiveComparer.Instance);
    }

b 的值是一个包含 A 的 IEnumerable。因为我要求 SortedSet 中除 a/A 之外的所有值,我不应该得到一个空集作为结果吗?我对此很困惑。

谢谢!

问题是您没有覆盖 GetHashCode"A".GetHashCode() returns 与 "a".GetHashCode() 不同的值。

解决此问题的快速方法是将 GetHashCode 函数更改为:

public int GetHashCode(string a)
{
    return a.ToLower().GetHashCode();
}

还有,你知道StringComparer吗?您可以将代码更改为:

var b = a.Except(new string[] { "a" }, StringComparer.InvariantCultureIgnoreCase);

而且不必担心实现自己的比较器