C# 如果我的类实现了IEqualityComparer,我应该实现非泛型GetHashCode和Equals吗<;T>;?
如果我的类实现了C# 如果我的类实现了IEqualityComparer,我应该实现非泛型GetHashCode和Equals吗<;T>;?,c#,.net,clr,C#,.net,Clr,如果我的类实现了IEqualityComparer,我应该实现非泛型的GetHashCode和Equals 更新: 我希望微软在推出IEqualityComparer时能够更新他们的产品系列的实现。因此,我认为Dictionary和任何其他集合类将在内部检查我的类是否实现了IEqualityComparer,并且仅当接口未实现时才使用非泛型方法GetHashCode和Equals。如果没有集合支持,该接口就没有什么价值 更新2: 我刚刚用ILSpy检查了Dictionary.FindEntry(
IEqualityComparer
,我应该实现非泛型的GetHashCode
和Equals
更新:
我希望微软在推出IEqualityComparer
时能够更新他们的产品系列的实现。因此,我认为Dictionary
和任何其他集合类将在内部检查我的类是否实现了IEqualityComparer
,并且仅当接口未实现时才使用非泛型方法GetHashCode
和Equals
。如果没有集合支持,该接口就没有什么价值
更新2:
我刚刚用ILSpy检查了Dictionary.FindEntry(TKey)。它使用IEqualityComparer
(下面的变量比较器
)。事实上,我根本没有发现使用非泛型的GetHashCode
和Equals
函数
int num = this.comparer.GetHashCode(key) & 2147483647;
for (int i = this.buckets[num % this.buckets.Length]; i >= 0; i = this.entries[i].next)
{
if (this.entries[i].hashCode == num
&& this.comparer.Equals(this.entries[i].key, key))
{
return i;
}
}
因此,我的类似乎只需要实现IEqualityComparer
,就可以正确地与Dictionary
一起使用
我理解,为了以防万一,实现非泛型函数不会有什么害处
但是,如果时间没有价值,我们应该花时间吗
我会让我的问题更具体:
如果我的类实现了IEqualityComparer
并且:
GetHashCode
和Equals
方法IEqualityComparer
应该在我的类中实现。在这种情况下,我们将在一个地方有泛型和非泛型的方法版本。
这不是应该如何使用IEqualityComparer
。它应该作为单独的类实现,并用作参数
谢谢大家。视情况而定
IEqualityComparer
用于比较类型T
的两个实例,通常由单独的比较器类实现。通常,您不会在类类型t
中实现这一点。它的目的是提供一个可供选择的比较,以便与支持his的类型一起使用
如果您是在类本身中实现这一点,您通常会实现
这就是说,重写Object.Equals
通常非常有用,因为您可以使用IEquatable.Equals
方法来实现Object.Equals
。这使得它实现起来“便宜”。由于可以使用Object.Equals
,它将为相等提供一致的含义,因此通常最好实现
如果要将对象用作哈希中的键,例如
字典
或哈希集
,则应重写GetHashCode
。如果有可能以这种方式使用它,重写此方法是有益的。通常,我发现在任何时候实现相等时重写GetHashCode
都很有用,以防我以后将该类型用作键。IEqualityComparer用于替换GetHashCode的默认实现,并等于所有.NET对象已经具有的值。此接口仅由字典和(散列)集使用,以使用不同的散列和比较方案,就像对象默认使用的那样
如果您的对象在字典和哈希表中用作键,您应该首先重写Equals和GetHashCode,让集合/字典为您的对象使用默认的比较器(您称之为EqualityComparere.default的比较器),该比较器无论如何都会调用对象的Equals和GetHashCode
通过IEqualityComparer提供外部比较器的唯一原因是使用不同的比较方案。例如,对于字符串,您可以从BCL类中选择区分大小写和不区分大小写的变体
更新1
这个问题的目的是为什么列表和其他集合总是使用默认的比较器,而不是对象提供的比较器。如果一个对象已经实现了Equals和GetHashCode,那么如果该对象同时也实现了IEqualityComparer,为什么List不应该使用它们呢?由于List不提供允许使用不同比较器的ctor,因此需要使用默认比较器
但是,如果您想使用不同的方法,您总是可以使用LINQ,它允许您为特定方法明确地传递自己的比较器,从而解决这个问题。例如,有一个过载,您可以通过自己的比较器
从MSDN样本:
Product[] fruits = { new Product { Name = "apple", Code = 9 },
new Product { Name = "orange", Code = 4 },
new Product { Name = "lemon", Code = 12 } };
Product apple = new Product { Name = "apple", Code = 9 };
Product kiwi = new Product {Name = "kiwi", Code = 8 };
ProductComparer prodc = new ProductComparer();
bool hasApple = fruits.Contains(apple, prodc);
bool hasKiwi = fruits.Contains(kiwi, prodc);
如果我理解正确,您会问如果您也必须实施
IEqualityComparer
如果您实施IEqualityComparer
,那么答案是您不必这样做,但这可能是个好主意。它只会使您的比较器与现有代码更兼容。您真的在谈论IEqualityComparer
还是IEquatable
?我是说IEqualityComparer。如果在集合中使用类,则应始终将Equals与GetHashCode配对。相关:您认为集合/字典在内部不使用IEqualityComparer吗?你能发个链接吗。谢谢。集合/字典使用EqualityComparer。默认类型返回集合/字典使用的EqualityComparer实例(它实现IEqualityComparer)。你可以通过反射器这样的反编译器直接检查,只是反编译。。。