从 CLR 的角度来看,IEqualityComparer
为==
您将在IEqualityComparer<T>
? 如果是这样,你什么时候会用一个来对抗另一个?
编辑
好的,Hashtable 的实现使用的 IEqaulityComparer 确实是有道理的——当我发布这个问题时,它从我的脑海中溜走了。那么 IEnumerable 的 Linq 的扩展呢?这是否意味着.net 在执行这些扩展方法时会建立一个 Hashtable?
从 CLR 的角度来看,IEqualityComparer
为==
您将在IEqualityComparer<T>
? 如果是这样,你什么时候会用一个来对抗另一个?
编辑
好的,Hashtable 的实现使用的 IEqaulityComparer 确实是有道理的——当我发布这个问题时,它从我的脑海中溜走了。那么 IEnumerable 的 Linq 的扩展呢?这是否意味着.net 在执行这些扩展方法时会建立一个 Hashtable?
IEqualityComparer由Hashtable、NameValueCollection和OrderedDictionary类使用,以支持您的类型的“平等”的自定义定义。这就是它提供GetHashCode()的原因,这与相等性本身没有太大关系。
如果你不提供IEqualityComparer
,上面提到的类将默认为Object.Equals(),它实现了引用相等。operator ==
在这种情况下不会调用重载。
编辑:一些 LINQ 的扩展方法确实将 aIEqualityComparer
作为参数,但原理保持不变:如果未指定该参数,则该方法最终将比较引用,而不是值,并且operator ==
不会被调用。
IEqualityComparer
不是 equal
,equal 用于对象(实例方法),但 EqualityComparer 用于装饰,例如在 linq 中你想要做特定的不同:
personList.OrderBy(p=>p.ID).Distinct(new MyEqualityComparer())
和
class MyEqualityComparer: IEqualityComparer<Person>
{
public bool Equals(Person p1, Person p2)
{
if (p1.Age == p2.Age)
return true;
return false;
}
public int GetHashCode(Person p)
{
return p.Id.GetHashCode();
}
}
但对于 Person 而言,equal 是:
public class Person
{
public int ID{get;set;}
public int Age{get;set;}
public override bool Equals(object o)
{
//do stuff
}
}
您可以通过 IEqualityComparer 进行任意数量的装饰,但不能通过实例方法进行此操作(您可以编写 personList.Distinct(new AnotherComparer) ,...)
IEqualityComparer
例如用于比较Dictionary<TK,TV>
。
它与覆盖运算符完全不同,==
因为实际上Dictionary
(以及通常无论使用什么IEqualityComparer
)不会对==
运算符进行任何调用。
最多,您可以比较“实现IEqualityComparer
”与“覆盖GetHashCode
和Equals
方法”,因为实际上它们是获得相同事物的两种方法(我会说它们与我相同)。