String.Equals(a,b)如何不产生StackOverflowException?


159

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

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

更新:我让JetBrains知道了,他们将其作为dotPeek的关键优先事项。https://youtrack.jetbrains.com/issue/DOTP-6789

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

字符串相等


免费的.NET Reflector(v6)在C#中将其显示为“错误”(即,仅显示a == b),但在VB.NET中是正确的:a Is b
Mark Hurd 2014年

Answers:


217

您的反编译器有错误。实际的代码不检查a == b,而是(Object)a == (Object)b绕过重载的运算符进行检查。


4
@Aravol是对的,但消息来源是最近才发布的
Dustin Davis

2
无论如何,这都是很模糊的代码。一个简单的object.ReferenceEquals(a,b)将是更加清晰..
VOO

1
@Voo我认为当前版本更加清晰。您不需要对转换object.ReferenceEquals版本有任何了解(例如,如果a是,则是null什么),并且,只要您知道转换是什么,就肯定不会混淆。
wchargin 2014年

72
“您的反编译器有错误”。放下麦克风。
espinchi 2014年

1
@Voo我的猜测:MS认为(Object)a == (Object)b并且Object.ReferenceEquals(a, b)具有相同的可读性,但是Object.ReferenceEquals(a, b)如果达到最大内联深度只有一点机会不内联,这也不会令我感到惊讶。MS进行了许多微优化,因为用户代码中的大多数紧密循环最终都会调用MS代码。

50

是来自Microsoft的真实代码。运营商==正在实施的小号

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

操作员==调用String.Equals ,其实现为:

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,然后进行比较来完成的。因此,这不会==在字符串类中调用重载运算符。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.