我想了解应该使用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. Java:<init>和<clinit>和有什么不一样?
- 2. <% %>和<%= %>和有什么不一样?
- 3. 部队更新TGT
- 4. GSSManager.createCredential如何获取Kerberos密钥和TGT?
- 5. C#-IComparable <T>和IEquatable <T>
- 6. vim中的<C-C>和<C-[>和有什么不一样?
- 7. 为什么在Javascript和PHP中LShift(<<)不一样?
- 8. 不能设置为空的特性“TGT”
- 9. 由TGT创建iSCSI目标不能
- 10. <?有什么区别? echo __();和<= __();
- 11. <%# %>和<%= %>有什么区别?
- 12. Django CAS和TGT(Ticket Granting Tickets)和服务票证验证
- 13. <%:和<%=和<%#在aspx中有什么区别?
- 14. 为什么IEqualityComparer <T>在.NET中扩展IEqualityComparer
- 15. 为什么我们需要IEqualityComparer,IEqualityComparer <T>接口?
- 16. 什么是Swift上的+++和<<<?
- 17. 加入+ IEqualityComparer <T>和HashCode
- 18. 什么意思是“:”在<%中:和<%=有什么区别?
- 19. IComparable和IEquatable接口有什么区别?
- 20. .hlsl和.hlsli和有什么不一样?
- 21. 使用服务负责人获得TGT
- 22. ASP.NET - <%@和<asp:Panel?是什么意思?
- 23. 为什么回显<<< _END和_END;不工作,仍然没有空白
- 24. cout << cout和cout <<&cout在C++中有什么区别?
- 25. IEquatable <'1>在接口
- 26. 什么是$ @和$ <Makefile?
- 27. windows XP和unix中kerberos门票TGT和服务门票的路径?
- 28. mysqlimport和mysql有什么区别<dbfile.sql
- 29. 为什么=和< - 在()中不等价?
- 30. 为什么ICollection <>。包含忽略我重写的Equals和IEquatable <>接口?
这个问题需要更多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