【问题标题】:How does String.Equals(a,b) not produce a StackOverflowException?String.Equals(a,b) 如何不产生 StackOverflowException?
【发布时间】:2014-12-10 19:21:54
【问题描述】:

在检查String == 运算符时,我注意到它调用String.Equals(string a, string b),这意味着它只是一个传递。

检查String.Equals(string a, string b) 方法,我发现它使用== 运算符进行相等性检查。在执行"x" == "x""x" == "y" 之类的操作时,这实际上是如何工作的并且不会导致StackOverflowException

更新:我让 JetBrains 知道,他们将其作为 dotPeek 的重中之重。 https://youtrack.jetbrains.com/issue/DOTP-6789

我还在 ILSpy 的 GitHub 存储库上添加了一个问题。

【问题讨论】:

  • 免费的 .NET Reflector (v6) 在 C# 中显示“错误”(即它只显示 a == b),但在 VB.NET 中正确:a Is b

标签: c# .net


【解决方案1】:

您的反编译器有错误。 The real code 不检查 a == b,它检查 (Object)a == (Object)b,绕过重载的运算符。

【讨论】:

  • @Aravol true,但源代码最近才发布
  • 无论如何,这都是相当模糊的代码。一个简单的object.ReferenceEquals(a,b) 会更清晰..
  • @Voo 我认为当前版本更清晰。你不需要知道任何关于 object.ReferenceEquals 的演员版本(例如,如果 anull 怎么办?),而且,只要你知道演员表是什么,它肯定不会被混淆。
  • "您的反编译器有错误"。放下麦克风。
  • @Voo 我的猜测:MS 认为 (Object)a == (Object)bObject.ReferenceEquals(a, b) 的可读性差不多,但如果 Object.ReferenceEquals(a, b) 在最大内联的情况下有一点机会不被内联,我也不会感到惊讶深度达到。 MS 做了很多微优化,因为用户代码中的大多数紧密循环最终都会调用 MS 代码。
【解决方案2】:

Here 是来自微软的真实代码。运算符==implemented as

public static bool operator == (String a, String b) {
   return String.Equals(a, b);
}

运营商== 调用String.Equals which is implemented 为:

public static bool Equals(String a, String b) {
    if ((Object)a==(Object)b) {
        return true;
    }

    if ((Object)a==null || (Object)b==null) {
        return false;
    }

    if (a.Length != b.Length)
        return false;

    return EqualsHelper(a, b);
}

如您所见,字符串相等性的比较是使用if ((Object)a==(Object)b) 将字符串转换为object 然后进行比较。所以这不会调用字符串类中的重载运算符==

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2014-03-29
    • 2019-12-28
    • 2021-10-06
    • 1970-01-01
    • 2015-07-05
    • 2011-10-20
    • 1970-01-01
    相关资源
    最近更新 更多