【问题标题】:Legitimate uses of ReferenceEquals()ReferenceEquals() 的合法使用
【发布时间】:2012-03-28 15:38:45
【问题描述】:

在遵循声明式风格编写的 .NET 程序中,ReferenceEquals() 有哪些合法用途?

【问题讨论】:

  • 当您想回答“这两个引用是否引用同一个对象”的问题时,一个合法的用途是?
  • 声明式风格到底是什么意思,这与引用相等有什么关系?
  • @GregC 知道,显然知道,但是每个阅读代码的程序员都知道吗,而不必去查找?
  • 对于预计不会覆盖Equals 的类,非虚拟ReferenceEquals 方法比使用Equals 及其关联的虚拟调度更快。速度优势足以证明使用它代替Object.Equals(Object,Object) 是合理的。一个更有趣的问题是,当Equals(X,Y) 为真但ReferenceEquals(X,Y) 为假时,是否应该将其视为违反封装。恕我直言,在非常真实的意义上它应该。
  • @GregC:让 C# 中的 == 运算符调用 Object.Equals 而不是执行等效于 ReferenceEquals 的引用比较,会使很多代码运行得更慢。从概念上讲,给定string s1="0"; string s2=0.ToString(); string s3=s1;",应该无法判断s3 是从s2 还是s1 复制的,但是确保包含相同字符的所有字符串确实无法区分将是昂贵的,并且不会真正提供太多好处。

标签: c# .net pointers collections reference


【解决方案1】:

不确定您所说的“编写为遵循声明式风格”是什么意思,但 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) 来检查引用是否相等.这 而是创建对重载运算符 == 的调用,从而导致 无限循环。使用 ReferenceEquals 或将类型转换为 Object,以 避免循环。

【讨论】:

  • @GregC 此处检查是必要的,否则null==null 场景将中断。另请注意,null 检查自己使用引用相等。他们只是使用cast-to-object 而不是ReferenceEquals。 (ReferenceEquals(a,b) 等价于(object)a==(object)b
  • @GregC 不能保证是一样的,但从上下文看来它应该是一样的。如果它的行为不同,那很可能是因为深度相等部分的错误。
  • 如果没有检查 ReferenceEquals 并且 a 和 b 都为 null,这将返回 false。实际上,它返回 true。
  • 在那里进行空检查异或可能是有意义的。它在技术上与它正在做的事情一致,并消除了对先前检查的无证依赖。它也对实际性能没有影响,只是可读性和可维护性。
【解决方案2】:

在遵循声明式风格编写的 .NET 程序中,ReferenceEquals() 有哪些合法用途?

无论编写程序的“风格”如何,ReferenceEquals 只有一种合法用途:比较两个引用的引用相等

如果您将 ReferenceEquals 用于比较两个引用的引用相等性之外的其他事情,那么您可能做错了什么。

【讨论】:

  • 我的口味有点重复。
  • @CodeInChaos:同义反复,当然。但是考虑一下使用 GetHashCode 来平衡哈希表以外的事情的人数。或者在需要字符串equality时使用字符串ordering的人数。或者当他们表示 Any() 时使用 Count() 的人数。
  • @GregC:如果您想要更具体的答案,请提出更具体的问题。
  • @GregC:你不会从我那里得到任何争论。有多少种不同的方法可以比较两个事物的相等性,这完全令人困惑,当你把排序混在一起时,情况会变得更糟。
  • @dnkulkarni:编译器生成参考比较。
【解决方案3】:

好吧,如果相关对象的设计和/或使用使得任何对象的实例永远不会超过一个实例与其他对象“相等”,那么它将是正确的,并且可能会更快而不是比较一些实例变量。

或者,正如在另一个答案中发布的那样,您可以先将其作为“轻松退出”进行检查,并且仅在它们不同时执行深度相等检查。这种用法只是一种性能改进。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多