public class LambdaEqualityComparer<T> : IEqualityComparer<T> { private readonly Func<T, T, bool> _equalsDelegate; public LambdaEqualityComparer(Func<T, T, bool> equalsDelegate) { _equalsDelegate = equalsDelegate; } public bool Equals(T x, T y) { Console.WriteLine($"Equals({x}, {y})"); return _equalsDelegate(x, y); } public int GetHashCode(T obj) { return 0; } public static implicit operator LambdaEqualityComparer<T>(Func<T, T, bool> equalsDelegate) { return new LambdaEqualityComparer<T>(equalsDelegate); } }
public class Test { public int X { get; set; } public int Y { get; set; } public override string ToString() => $"Test{{X: {X}, Y: {Y}}}"; }
private static void Main(string[] args) { var tests1 = Enumerable.Range(1, 3).Select(it => new Test {X = it, Y = 1}); var r = tests1.Distinct((LambdaEqualityComparer<Test>)((x, y) => x.Y == y.Y)).ToArray(); Console.WriteLine("结果==================="); foreach(var t in r) { Console.WriteLine(t); } }
Equals(Test{X: 1, Y: 1}, Test{X: 2, Y: 1}) Equals(Test{X: 1, Y: 1}, Test{X: 3, Y: 1}) 结果=================== Test{X: 1, Y: 1}
修改GetHashCode
public int GetHashCode(T obj) { return obj.GetHashCode(); }
结果=================== Test{X: 1, Y: 1} Test{X: 2, Y: 1} Test{X: 3, Y: 1}
我的理解是GetHashCode是更轻量级的比较,但结果不够准确。HashCode相同的对象,一定是相同的,HashCode不相同的对象不一定就不相同,需要Equals方法比较。
我在网上找了一些文章,说明的也是跟我理解的差不多。
但是实际使用下来并不是这样的,这是为什么?是哪里有问题吗?
你这一句你仔细看一下
“GetHashCode是更轻量级的比较,但结果不够准确。HashCode相同的对象,一定是相同的,HashCode不相同的对象不一定就不相同”
“如果HashCode相同的一定相同,不同的一定不相同”跟“结果不够准确”是相互矛盾的。
事实是
HashCode相同的可能不同,不同的一定不相同,才是“结果不够准确”。
我觉得你把我的话复制一遍不够,你得抄一遍...不过也得亏你复制了一遍,免得说是我把问题改了。
“HashCode相同的可能不同,不同的一定不相同”,那默认每个对象的GetHashCode都不同,难道每个对象都是一定不同?说不过去把。
又翻看了几篇,看来是我看得第一篇太水了...
@百香居士: 人家说的是正确的,是你理解反了。关于GetHashCode不同就表示一定不同,是框架要这样觉得,不是你觉得,这句话完整的表述是“GetHashCode不同框架就【视为】不同”,所以不再走Equals。