簡體   English   中英

如果我的類實現了IEqualityComparer,我應該實現非通用GetHashCode和Equals嗎? <T> ?

[英]Should I implement non-generic GetHashCode and Equals if my class implements IEqualityComparer<T>?

如果我的類實現IEqualityComparer<T>是否應該實現非通用GetHashCodeEquals

更新:我希望MS在引入IEqualityComparer<T>時更新其集合的實現。 因此,我認為Dictionary和其他任何收集類都將在內部檢查我的類是否實現IEqualityComparer<T> ,並且僅在未實現該接口的情況下才使用非通用方法GetHashCodeEquals 沒有集合支持,該接口幾乎沒有價值。

Update2:我剛剛使用ILSpy檢查了Dictionary.FindEntry(TKey key) 它使用IEqualityComparer<TKey> (下面的可變comparer )。 實際上,我根本沒有發現任何非通用GetHashCodeEquals函數的使用。

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<T>即可與Dictionary一起正確使用。

我知道,以防萬一,實現非通用功能不會有任何危害。

但是,如果沒有任何價值,我們應該花費時間嗎?

我將提出更具體的問題:

如果我的類實現了IEqualityComparer<T>並且應該實現非通用GetHashCodeEquals則:

  1. 我在代碼中不使用非通用集合
  2. 第三方代碼不會調用我的代碼的GetHashCodeEquals方法。

Microsoft代碼是否仍需要非通用版本才能正常工作?

Update3 :我想我明白了。 我認為IEqualityComparer<T>將在我的課程中實現。 在那種情況下,我們將在一個地方擁有方法的通用版本而非通用版本。 那不是應該使用IEqualityComparer<T>方式。 應該將其實現為單獨的類並用作參數。

感謝大家。

這取決於。 IEqualityComparer<T>用於比較類型T兩個實例-通常由單獨的比較器類實現。 通常,您不會在類類型T實現它。 它旨在提供另一種比較,以與支持他的類型一起使用。

如果要在類本身中實現此功能,則通常要實現IEquatable<T>

話雖如此,重寫Object.Equals通常很有用,因為您可以使用IEquatable<T>.Equals方法來實現Object.Equals ,這通常非常簡單。 這使得實施“便宜”。 由於可能使用Object.Equals ,它將為相等性提供一致的含義,因此通常實現是一個好主意。

如果您的對象將用作哈希(例如Dictionary<T,U>HashSet<T> ,則應重寫GetHashCode 如果甚至有可能以這種方式使用它,則重寫此方法將是有益的。 通常,我發現在實現相等性的任何時候重寫GetHashCode都是有用的,以防萬一我以后將類型用作鍵。

IEqualityComparer旨在替換GetHashCode的默認實現,並等於每個.NET對象已經擁有。 默認情況下,此字典接口僅由Dictionary和(Hash)Set用來將不同的哈希和比較方案用作對象。

如果您的對象在“字典”和“哈希表”中用作鍵,則應首先覆蓋Equals和GetHashCode,以使Sets / Dictionaries為您的對象使用默認的比較器(您將其稱為EqualityComparere.Default),該比較器會調用對象的Equals和GetHashCode無論如何。

通過IEqualityComparer提供外部比較器的唯一原因是使用不同的比較方案。 例如,對於字符串,您可以從BCL StringComparer類中選擇區分大小寫和不區分大小寫的變體。

UPDATE1

這個問題的目的是為什么List和其他集合始終使用默認比較器,而不使用對象提供的比較器。 如果一個對象確實已經實現了Equals和GetHashCode,如果該對象同時也實現了IEqualityComparer,為什么List不應該使用它們? 由於List沒有提供允許使用其他比較器的ctor,因此確實需要使用默認比較器。

但是,如果您想使用不同的比較器,則始終可以使用LINQ,它可以通過允許您明確地傳遞自己的特定方法的比較器來解決此問題。 例如Enumerable.Contains有一個重載,您可以在其中傳遞自己的比較器。

從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<T> ,那么答案是不必這樣做,但這可能是個好主意。 這只會使您的比較器與現有代碼更加兼容。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM