Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/20.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 如果我的类实现了IEqualityComparer,我应该实现非泛型GetHashCode和Equals吗<;T>;?_C#_.net_Clr - Fatal编程技术网

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
    方法
  • Microsoft代码是否仍然需要非通用版本才能正常工作

    更新3: 我想我明白了。我认为
    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)。你可以通过反射器这样的反编译器直接检查,只是反编译。。。