2010-07-20 100 views
16

IEquatable <T>可能已被聲明爲T中的逆變,因爲它僅在輸入位置使用T(或者等價地,U是T的子類型應該暗示IEquatable <T>是[IEquatable的子類型<U>)。爲什麼IEquatable T不會在T中針對C#4.0逆轉?

那麼,爲什麼BCL團隊沒有使用'in'關鍵字來註釋它(對於C#4.0),就像他們對許多其他通用接口(如完全類似的IComparable)所做的那樣?

+0

在線程中提到的問題[應該'IEquatable ','IComparable '在非'sealed'類上實現嗎?](http://stackoverflow.com/questions/1868316/should-iequatablet-icomparablet-如果IEquatable <>'是逆變的,那麼就會變得更糟糕。 – 2013-07-09 22:32:39

回答

13

我認爲這主要是出於哲學原因,而不是技術限制–,因爲它可以簡單地註釋接口。 IEquatable<T>旨在比較相同類型的對象以確保相等。超類的實例通常不被認爲等於子類的實例。這種意義上的平等也意味着類型平等。這與IComparable<in T>有點不同。在不同類型中定義相對排序順序可能是明智的。

引述MSDN page on IEquatable<T>

對實施者的說明:

更換IEquatable<T>接口的類型參數與是實現此接口類型。

這句話進一步證明IEquatable<T>是爲了在單個具體類型的實例之間工作的事實。

+0

謝謝;我懷疑這很接近事實。這似乎是一個恥辱,雖然,因爲U是T的一個子類型,這確實意味着IEquatable T與U相等......這對U而言並不是IEquatable!換句話說,我沒有看到任何註釋界面的缺點...... – 2010-07-20 11:57:03

+0

我真的沒有看到任何*上行*使其逆轉。說'Vehicle'的一個實例與'Car'的一個實例完全等同 - 實際上完全相同是沒有意義的。它們可以等同於排序順序(與IComparable一樣),但它們永遠不會真正「相等」。 – 2010-07-20 12:04:45

+1

@Khalid:考慮到一個理想的基本類型不應該知道其派生類型的細節,它不能決定這些類型的相等性。派生類可能會添加一些屬性,因此與基類提供的相等定義不同。 – 2010-07-20 12:05:52

1

可繼承類型通常不應該實現IEquatable<T>。如果IEquatable<T>包括GetHashCode()方法,則可以定義IEquatable<T>的語義以表示當檢查爲T時項目應該相等。不幸的是,IEquatable<T>被綁定到與Object.Equals相同的哈希碼的事實意味着通常IEquatable<T>必須實現與Object.Equals基本相同的語義。

因此,如果IEquatable<BaseClass>的實施確實不是其中調用Object.Equals其他任何東西,這將覆蓋Object.EqualsGetHashCode(),並且不派生類中重新實現IEquatable<BaseClass>將結束與一個破碎的實現,接口;一個IEquatable<BaseClass>的實現簡單地稱爲Object.Equals即使在這種情況下也可以正常工作,但對於沒有實現IEquatable<T>的類沒有任何實際優勢。

鑑於可繼承類首先不應該實現IEquatable<T>,協方差的概念與接口的正確實現無關。

相關問題