有2个比较器:
public class EqualityComparer123 : IEqualityComparer<ClassA> { Func<ClassA, ClassA, bool> pred; public EqualityComparer123(Func<ClassA, ClassA, bool> pred) { this.pred = pred; } public bool Equals(ClassA x, ClassA y) { //return x.id == y.id; return pred(x, y); } public int GetHashCode(ClassA obj) { return base.GetHashCode(); } } public class TEqualityComparer<T> : IEqualityComparer<T> { Func<T, T, bool> pred; public TEqualityComparer(Func<T, T, bool> pred) { this.pred = pred; } public bool Equals(T x, T y) { return pred(x, y); } public int GetHashCode(T obj) { return obj.GetHashCode(); } }
类有:
public class ClassA { public int id { set; get; } public string name { set; get; } }
代码:
var ca = new List<ClassA>(); ca.Add(new ClassA() { id = 1, name = "nima" }); ca.Add(new ClassA() { id = 2, name = "tama" }); var cb = new List<ClassA>(); cb.Add(new ClassA() { id = 1, name = "nima2" }); cb.Add(new ClassA() { id = 3, name = "tama2" }); var Compare = new EqualityComparer123((x, y) => { return x.id == y.id; }); var query = ca.Join(cb, x => x, y => y, (x, y) => new { CA = x, CB = y }, Compare); var Compare3 = new TEqualityComparer<ClassA>((x, y) => { return x.id == y.id; }); var query3 = ca.Join(cb, x => x, y => y, (x, y) => new { CA = x, CB = y }, Compare3);
其中query1能够查询出数据,而query3却查询不出数据,望解惑。。
ClassA加上下面方法,Query3也能查出来了:
public override int GetHashCode()
{
return id;
}
你打个断点就知道,如果IEqualityComparer获取的HashCode不相等,那它的Equal方法都不执行。
你EqualityComparer123 获取能查询是因为错上加错,反而能执行了:
1、默认的ClassA 没重写GetHashCode 会导致即使id相同,但是不Hash值不相等
2、EqualityComparer123 的 GetHashCode(ClassA obj)返回EqualityComparer123自己的hash值,避免调用了步骤1的错误hash值。
虽然错上加错能运行,但是有很大的性能问题。因为EqualityComparer123获取的classA的hash值是固定值,没有了预筛选的功能。