26

我有一个关于Object.Equals和的问题Equals(object)。我的示例代码如下:

class Program
{
    static void Main(string[] args)
    {
        var sb1 = new StringBuilder("Food");
        var sb2 = new StringBuilder("Food");
        Console.WriteLine(sb1 == sb2);
        Console.WriteLine(sb1.Equals(sb2));
        Console.WriteLine(Object.Equals(sb1, sb2));
        Console.WriteLine(Object.ReferenceEquals(sb1, sb2));
        Console.ReadLine();
    }
}

输出是:

False
True
False
False

但就我所关心的Object.Equals(sb1, sb2)内部调用 而言sb1.Equals(sb2),为什么它会给出两种不同的结果呢?

4

3 回答 3

18

你错过了另一个测试:

Console.WriteLine(sb1.Equals((object)sb2)); // False!

StringBuilder 不覆盖Equals(object),它用另一个重载Equals(StringBuilder)它。

Object.Equals(object, object)正在调用Equals(object),所以结果为假。

于 2013-05-05T09:13:28.323 回答
4

您正在使用 4 种不同的比较方法,导致不同的结果:

  • 操作员==默认会检查引用是否相等。在这种情况下,您有两个实例,因此它们确实有两个不同的引用。的行为==可以被任何类型覆盖(比如string有自己的比较方法),但如果StringBuilder不是。
  • 方法StringBuilder.Equals(StringBuilder)将与另一个 StringBuilder 进行比较并比较一些内部值。在您的情况下,这些值是相同的。奇怪的是,StringBuilder它不会覆盖StringBuilder.Equals(object)应用相同逻辑的方法。
  • 方法object.Equals(object, object)将尝试调用.Equals(object)其中一个对象的方法。在这种情况下:StringBuilder.Equals(object)正如我所说,它没有比较值的逻辑。结果只是比较了两个实例的引用。
  • Object.ReferenceEquals只会比较参考。

有关详细信息,请参阅:

于 2013-05-05T09:15:39.957 回答
3

StringBuilder.equals 不比较对象,而是来自MSDN

“如果此实例和 sb 具有相等的stringCapacityMaxCapacity值,则为真;否则为假。”

您正在进行的其余检查会比较参考。

于 2013-05-05T09:15:40.913 回答