我最近遇到了这个问题,到目前为止,我一直很高兴地重写相等运算符 (==) 和/或 Equals 方法以查看两个引用是否类型实际上包含相同的数据(即两个看起来相同的不同实例)。
自从我越来越多地参与自动化测试(将引用/预期数据与返回的数据进行比较)以来,我一直在更多地使用它。
在查看一些 coding standards guidelines in MSDN 时我遇到了 article建议反对它。现在我明白了为什么这篇文章是这样说的(因为它们不是同一个实例)但它没有回答问题:
- 比较两种引用类型的最佳方法是什么?
- 我们应该实现 IComparable ? (我还看到提到这应该只为值类型保留)。
- 是否有一些我不知道的接口(interface)?
- 我们应该自己动手吗?!
非常感谢^_^
更新
看起来我误读了一些文档(这是漫长的一天)并覆盖了 Equals可能是要走的路..
If you are implementing reference types, you should consider overriding the Equals method on a reference type if your type looks like a base type such as a Point, String, BigNumber, and so on. Most reference types should not overload the equality operator, even if they override Equals. However, if you are implementing a reference type that is intended to have value semantics, such as a complex number type, you should override the equality operator.
最佳答案
在 .NET 中正确、高效地实现相等性并且没有代码重复是很困难的。具体来说,对于具有值语义的引用类型(即 immutable types that treat equvialence as equality ),您应该实现 the System.IEquatable<T>
interface ,并且您应该实现所有不同的操作( Equals
、 GetHashCode
和 ==
、 !=
)。
例如,这是一个实现值相等的类:
class Point : IEquatable<Point> {
public int X { get; }
public int Y { get; }
public Point(int x = 0, int y = 0) { X = x; Y = y; }
public bool Equals(Point other) {
if (other is null) return false;
<b>return X.Equals(other.X) && Y.Equals(other.Y);</b>
}
public override bool Equals(object obj) => Equals(obj as Point);
public static bool operator ==(Point lhs, Point rhs) => object.Equals(lhs, rhs);
public static bool operator !=(Point lhs, Point rhs) => ! (lhs == rhs);
public override int GetHashCode() => <b>X.GetHashCode() ^ Y.GetHashCode();</b>
}
以上代码中唯一可移动的部分是粗体部分:Equals(Point other)
中的第二行和 GetHashCode()
方法。其他代码保持不变。
对于不表示不可变值的引用类,不要实现运算符 ==
和 !=
.相反,使用它们的默认含义,即比较对象标识。
代码有意甚至将派生类类型的对象等同起来。通常,这可能是不可取的,因为基类和派生类之间的相等性没有明确定义。不幸的是,.NET 和编码准则在这里不是很清楚。 Resharper 创建的代码,已发布 in another answer , 在这种情况下容易出现不良行为,因为 Equals(object x)
和 Equals(SecurableResourcePermission x)
将以不同的方式处理这种情况。
为了改变这种行为,必须在强类型 Equals
中插入额外的类型检查。方法如上:
public bool Equals(Point other) {
if (other is null) return false;
if (other.GetType() != GetType()) return false;
<b>return X.Equals(other.X) && Y.Equals(other.Y);</b>
}
关于c# - 什么是用于比较引用类型的两个实例的 "Best Practice"?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/104158/