I'm using .NET 4.6 and I experienced serious strangeness. I'm trying to get an IEnumerable of all values from a sorted set that are NOT the case-insensitive equivalent of the passed in IEnumerable. From what I understand, that is the job of Except.
I have a class, CaseInsensitiveComparer which is implemented like so:
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();
}
}
I use it like this:
public void DotNetWeirdness()
{
var a = new SortedSet<string>();
a.Add("A");
var b = a.Except(new string[] { "a" }, CaseInsensitiveComparer.Instance);
}
The value of b is an IEnumerable containing A. Since I'm asking for all values in SortedSet except for a/A, shouldn't I have an empty set as the result? I'm quite confused by this.
Thanks!
The issue is that you're not overriding GetHashCode
. "A".GetHashCode()
returns a different value from "a".GetHashCode()
.
A quick way to fix this is to change the GetHashCode
function to this:
public int GetHashCode(string a)
{
return a.ToLower().GetHashCode();
}
Also, do you know about StringComparer
? You can change your code to this:
var b = a.Except(new string[] { "a" }, StringComparer.InvariantCultureIgnoreCase);
And not have to worry about implementing your own comparer
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.