C# 中实现相等性的最少代码

2024-01-13

In this ,Eric Lippert 在第 9 点中指出,C# 具有“太多的平等性”。他指出有 9 或 10 种不同的方法或运算符可以重载以提供对象相等性。

我的第一个问题是 - 如果重写 Object.Equals(object) 方法,编译器是否可以调用任何其他相等运算符,如 ==、!=、

在 C++ 中,这种行为是有先例的。复制构造函数可以在某些需要生成临时变量的地方被编译器调用。我至少 95% 确信这在 C# 中不会发生,但这实际上取决于编译器的构造方式,也可能取决于边缘情况。

第二个问题是 - 如果编译器永远不会间接调用任何相等运算符,那么对于小型、中型甚至大型项目来说,指定仅使用 Object.Equals(object) 方法和 IEquatable 是否可以?相等性测试,如果类型将用于排序或其他需要确定对象排名的时候,是否使用 IComparable?换句话说,如果项目中的每个人都同意不会使用其他相等运算符,因此没有必要,是否可以避免定义其他相等运算符?

假设代码仅在项目内使用,不会导出供第三方使用。


if the Object.Equals(object)方法被重写,编译器是否可以调用任何其他相等运算符,例如==, !=, <=等没有明确执行此操作的代码?

C# 编译器不知道Equals and ==在语义上是相同的。如果你打电话Equals然后该方法将被调用。

那么对于小型、中型甚至大型项目来说,指定仅Object.Equals(object)方法和IEquatable用于相等性测试,并且IComparable如果类型将用于排序或其他需要确定对象排名的时候使用?换句话说,如果项目中的每个人都同意不会使用其他相等运算符,因此没有必要,是否可以避免定义其他相等运算符?

你在这里遇到的危险是你会得到一个==为您定义的运算符默认引用相等。您很容易陷入超载的情况Equals方法确实重视平等并且==确实引用相等,然后您不小心对不引用相等但值相等的事物使用了引用相等。这是一种容易出错的做法,人工代码审查很难发现。

几年前,我研究了一种静态分析算法来统计检测这种情况,我们发现每百万行代码大约有两个实例的缺陷率在我们研究的所有代码库中。当仅考虑某些地方被覆盖的代码库时Equals,缺陷率显然要高得多!

此外,还要考虑成本与风险。如果您已经实现了IComparable那么编写所有的操作符就只是简单的一句台词,不会有错误,也永远不会改变。这是您要编写的最便宜的代码。如果要在编写和测试十几个小方法的固定成本与查找和修复使用引用相等而不是值相等的难以发现的错误的无限成本之间进行选择,我知道我会选择哪一个。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 中实现相等性的最少代码 的相关文章

随机推荐