在遵循声明式编程风格的.NET程序中,ReferenceEquals()有哪些合法使用?
不确定你所说的“按照声明式风格编写”的含义是什么,但通常在重载==
运算符时使用ReferenceEquals
。来自http://msdn.microsoft.com/en-us/library/ms173147.aspx:
public static bool operator ==(ThreeDPoint a, ThreeDPoint b)
{
// If both are null, or both are same instance, return true.
if (System.Object.ReferenceEquals(a, b))
{
return true;
}
// If one is null, but not both, return false.
if (((object)a == null) || ((object)b == null))
{
return false;
}
// Return true if the fields match:
return a.x == b.x && a.y == b.y && a.z == b.z;
}
重要提示请看下面的注释:
注:在重载运算符==时常见的一个错误是使用(a == b)、(a == null)或(b == null)来检查引用相等性。这会导致调用重载的operator==,从而导致无限循环。使用ReferenceEquals方法,或将类型强制转换为Object类型,以避免循环。
null==null
的情况会出问题。另外请注意,这些 null
检查本身使用引用相等性。它们只是使用对象转换而不是 ReferenceEquals
。(ReferenceEquals(a,b)
等同于 (object)a==(object)b
) - CodesInChaos如果相关对象的设计和/或用法是这样的,即任何对象的实例都不会有多个“相等”,那么它将是正确的,并且比比较一些实例变量要快。
或者,如另一个答案中所发布的那样,您可以首先将其检查为“易于退出”,仅在它们不同的情况下执行深度相等检查。 这种用法只是性能提高。
Equals
的类,非虚拟的ReferenceEquals
方法比使用带有关联虚拟调度的Equals
更快。速度优势足以证明在Object.Equals(Object,Object)
的位置使用它是合理的。更有趣的问题是,当Equals(X,Y)
为真但ReferenceEquals(X,Y)
为假时是否应该认为违反了封装性。在我看来,从实质上讲,应该这样认为。 - supercat==
运算符调用Object.Equals
而不是执行与ReferenceEquals
等效的引用比较,会导致很多代码运行得更慢。从概念上讲,给定string s1="0"; string s2=0.ToString(); string s3=s1;"
,我们无法确定s3
是从s2
还是从s1
复制过来的,但确保所有包含相同字符的字符串真正无法区分将会非常昂贵,并且并没有太多好处。 - supercat