我想了解應該使用IEqualityComparer<T>
和IEquatable<T>
的情況。 兩者的MSDN文檔看起來非常相似。IEqualityComparer <T>和IEquatable <T>和有什麼不一樣?
回答
IEqualityComparer<T>
是一個對象的接口,用於對T
類型的兩個對象執行比較。
IEquatable<T>
適用於T
類型的對象,以便它可以與另一個對比。
+1 _IEquatable用於對象,以便它可以將其自身與相同類型的另一個**進行比較** – gdoron 2012-02-16 18:30:57
簡單,簡明且易於理解 – Tilak 2012-02-16 18:31:07
同上@Tilak ....不需要更多解釋 – rajibdotnet 2014-05-18 21:02:36
比較兩個T
s。另一個可以與其他T
相比較。通常,你只需要一次使用一個,而不是兩個。
IEqualityComparer用於兩個對象的相等性在外部實現,例如,如果你想爲兩種類型定義一個你沒有源代碼的比較器,或者兩種東西之間的相等只在某些有限的情況下才有意義。
IEquatable是爲了實現對象本身(被比較的是相等的)。
之間的差異同樣是唯一真正提出了「插入平等」(外部使用)問題的人加上1. – 2015-08-16 07:46:39
您已經得到了的基本定義,它們是。簡而言之,如果在類T
上執行IEquatable<T>
,Equals
方法,該類型爲T
的對象會告訴您對象本身(正在測試的相等性)是否等於另一個相同類型的實例T
。而IEqualityComparer<T>
用於測試任何兩個T
實例的相等性,通常在T
實例的範圍之外。
至於它們對於最初可能會引起混淆。根據定義,應該清楚的是,因此IEquatable<T>
(在類別T
中定義)應該成爲表示其對象/實例的唯一性的事實標準。 HashSet<T>
,Dictionary<T, U>
(考慮GetHashCode
也被覆蓋),Contains
在List<T>
等使用此。在T
上實施IEqualityComparer<T>
對上述一般情況沒有幫助。隨後,在除T
以外的任何其他類別上實施IEquatable<T>
價值不大。這個:
class MyClass : IEquatable<T>
很少有道理。
在另一方面
class T : IEquatable<T>
{
//override ==, !=, GetHashCode and non generic Equals as well
public bool Equals(T other)
{
//....
}
}
是它應該怎麼做。
IEqualityComparer<T>
在需要自定義驗證相等性時非常有用,但不作爲一般規則。例如,在Person
的某個等級中,您可能需要根據年齡測試兩個人的平等。在這種情況下,你可以這樣做:
class Person
{
public int Age;
}
class AgeEqualityTester : IEqualityComparer<Person>
{
public bool Equals(Person x, Person y)
{
return x.Age == y.Age;
}
public int GetHashCode(Person obj)
{
return obj.Age.GetHashCode;
}
}
對它們進行測試,嘗試
var people = new Person[] { new Person { age = 23 } };
Person p = new Person() { age = 23 };
print people.Contains(p); //false;
print people.Contains(p, new AgeEqualityTester()); //true
同樣IEqualityComparer<T>
上T
沒有意義。
class Person : IEqualityComparer<Person>
確實有效,但對眼睛看起來並不好,並且打敗了邏輯。
通常情況下,你需要的是IEquatable<T>
。理想情況下,您可以只有一個IEquatable<T>
,而根據不同的標準可以有多個IEqualityComparer<T>
。
的IEqualityComparer<T>
和IEquatable<T>
是完全類似Comparer<T>
和IComparable<T>
其用於比較目的,而不是等同;良好的線程here,我寫了同樣的答案:)
'public int GetHashCode(Person obj)'應該返回'obj.GetHashCode()' – 2016-12-02 18:16:14
@HristoYankov應該返回'obj.Age.GetHashCode'。將編輯。 – nawfal 2016-12-02 18:18:28
請解釋爲什麼比較器必須對它比較的對象的哈希值做出這樣的假設?你的比較器不知道人如何計算哈希值,爲什麼你會覆蓋它? – 2016-12-02 19:53:01
在決定是否使用IEquatable<T>
或IEqualityComparer<T>
, 人們可能要問:
有測試
T
兩個實例爲平等的首選方式,或者有幾種同樣有效的方法?
如果測試相等的
T
兩個實例,或者幾種方法之一是首選,然後IEquatable<T>
將是正確的選擇的方法只有一個:這個接口應該只執行T
本身,因此T
的一個實例具有關於如何將其本身與另一個T
實例進行比較的內部知識。在另一方面,如果有比較兩個
T
S代表平等幾個同樣合理的方法,IEqualityComparer<T>
似乎更爲合適:此接口並不意味着由T
本身來實現,而是通過其他的「外部」類。因此,在測試兩個實例T
以獲得相等時,由於T
對平等沒有內在的理解,因此您必須明確選擇一個根據您的具體要求執行測試的實例。
例子:
讓我們考慮這兩種類型(假設有value semantics):
interface IIntPoint : IEquatable<IIntPoint>
{
int X { get; }
int Y { get; }
}
interface IDoublePoint // does not inherit IEquatable<IDoublePoint>; see below.
{
double X { get; }
double Y { get; }
}
爲什麼會只有一個這種類型的繼承IEquatable<>
的,而不是其他?
理論上,只有一種比較兩種實例類型的明智方式:如果兩個實例中的X
和Y
屬性相等,則它們相等。根據這種想法,這兩種類型都應該執行IEquatable<>
,因爲似乎沒有其他有意義的方式進行平等測試。
這裏的問題是,comparing floating-point numbers for equality might not work as expected, due to minute rounding errors。有幾種不同的方法可以比較近似等於的浮點數,每種方法都具有特定的優點和折衷方案,您可能希望能夠選擇適合自己的方法。
sealed class DoublePointNearEqualityComparerByTolerance : IEqualityComparer<IDoublePoint>
{
public DoublePointNearEqualityComparerByTolerance(double tolerance) { … }
…
public bool Equals(IDoublePoint a, IDoublePoint b)
{
return Math.Abs(a.X - b.X) <= tolerance && Math.Abs(a.Y - b.Y) <= tolerance;
}
…
}
請注意,鏈接到(上面)的頁面明確指出,該測試近乎平等有一些缺點。由於這是一個IEqualityComparer<T>
的實現,如果它不夠用於您的目的,您可以將其交換出來。
由於任何合法的'IEqualityComparer
更好的例子是字符串之間的比較。只有字符串包含相同的字節序列時,纔將字符串視爲相等的字符串比較方法是有意義的,但還有其他有用的比較方法*也構成了等價關係*,例如不區分大小寫的比較。請注意,認爲「hello」等於「Hello」和「hElLo」的'IEqualityComparer
@supercat,感謝您的寶貴意見。我很可能在接下來的幾天內不會修改我的答案,所以如果您願意,請隨時根據需要進行修改。 – stakx 2013-03-20 08:28:54
- 1. Aurelia的<compose>和<require>和有什麼不一樣?
- 2. <% %>和<%= %>和有什麼不一樣?
- 3. Java:<init>和<clinit>和有什麼不一樣?
- 4. 部隊更新TGT
- 5. GSSManager.createCredential如何獲取Kerberos密鑰和TGT?
- 6. C#-IComparable <T>和IEquatable <T>
- 7. vim中的<C-C>和<C-[>和有什麼不一樣?
- 8. 爲什麼在Javascript和PHP中LShift(<<)不一樣?
- 9. 無法從AD獲得TGT
- 10. 不能設置爲空的特性「TGT」
- 11. 由TGT創建iSCSI目標不能
- 12. <?有什麼區別? echo __();和<= __();
- 13. <?有什麼區別?和<?php
- 14. <%# %>和<%= %>有什麼區別?
- 15. 錯誤與Cas SERVICE_TICKET_NOT_CREATED和TGT與JBoss 5.1.0一起銷燬.GA
- 16. <%:和<%=和<%#在aspx中有什麼區別?
- 17. Django CAS和TGT(Ticket Granting Tickets)和服務票證驗證
- 18. 爲什麼我們需要IEqualityComparer,IEqualityComparer <T>接口?
- 19. 爲什麼IEqualityComparer <T>在.NET中擴展IEqualityComparer
- 20. 什麼是Swift上的+++和<<<?
- 21. 加入+ IEqualityComparer <T>和HashCode
- 22. 爲什麼Array.IndexOf沒有檢查像List <T>這樣的IEquatable呢?
- 23. IComparable和IEquatable接口有什麼區別?
- 24. 什麼意思是「:」在<%中:和<%=有什麼區別?
- 25. 在ASP.NET WebForms中,<%:, <%=和<%#之間有什麼區別?
- 26. numpy.polyfit和scipy.polyfit和有什麼不一樣?
- 27. libicucore.dylib和libicucore.A.dylib和有什麼不一樣?
- 28. .hlsl和.hlsli和有什麼不一樣?
- 29. 使用服務負責人獲得TGT
- 30. 爲什麼defun不一樣(setq <name><lambda>)?
這個問題需要更多upvotes! – nawfal 2012-12-06 11:03:50
[MSDN sez:](https://msdn.microsoft.com/en-us/library/ms132151(v = vs.110).aspx)「此接口允許爲集合實現自定義相等比較**。 *「當然是在所選答案中推斷的。因爲'EqualityComparer'使用'IEquatable ' –
radarbob
2016-09-20 18:38:14
'測試相等性......上述建議我應該爲任何執行'IEquatable'的'T'創建一個自定義集合。像「List 」這樣的集合在其中是否存在某種微妙的錯誤? –
radarbob
2016-09-20 18:45:09