C# 中 == 运算符、StringBuilder.Equals、Object.Equals 和 Object.ReferenceEquals 方法的区别

26

我有一个关于 Object.EqualsEquals(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),那么为什么会得到两个不同的结果呢?


你应该想出一个更好的问题标题。目前的标题没有意义。请不要在标题中重复标签。 - Ondrej Tucny
@ReferenceEquals:您正在比较四种比较方法。我修改了您的标题以更好地反映您的问题。 - Martin Mulder
3
为什么你要检查两个字符串生成器的相等性?这就像检查一个流或文本编写器的相等性一样。 - leppie
3个回答

18

1
你应该解释一下 Object.Equals()IEquatable<T> 之间的区别。 - Matthew Watson
因为我们有两个不同的引用(对象,实例),默认的Equal(object)应该首先返回引用比较。 - Uzzy
1
@MatthewWatson - 我认为 StringBuilder 没有实现 IEquatable<T> 接口: http://msdn.microsoft.com/zh-cn/library/system.text.stringbuilder.aspx - Kobi
从您的链接中: 它确定两个对象是否表示相同的对象引用。如果是,则该方法返回true。此测试等效于调用ReferenceEquals方法。此外,如果objA和objB都为null,则该方法返回true。 - Uzzy
@Uzzy - 但是当引用不相等时会发生什么?在进行空值检查后,它会调用一个重写的.Equals(object)方法,这个方法可能会执行任何操作。顺便说一下,我不确定我完全理解你的意思。我的回答是否错误? - Kobi
显示剩余5条评论

4
您正在使用4种不同的比较方法,会导致不同的结果:
  1. 运算符==默认情况下会检查引用是否相等。在这种情况下,您有两个实例,因此它们具有两个不同的引用。可以通过任何类型(如string具有自己的比较方法)来覆盖==的行为,但在StringBuilder的情况下,它没有。
  2. 方法StringBuilder.Equals(StringBuilder)将与另一个StringBuilder进行比较并比较一些内部值。在您的情况下,这些值是相同的。奇怪的是,StringBuilder没有覆盖方法StringBuilder.Equals(object)以应用相同的逻辑。
  3. 方法object.Equals(object, object)将尝试调用其中一个对象的.Equals(object)方法。在这种情况下:StringBuilder.Equals(object) ,就像我说的那样,没有逻辑来比较这些值。从而仅比较两个实例的引用。
  4. Object.ReferenceEquals只比较引用。
更多信息,请参见以下链接:

3

StringBuilder.equals方法并不是比较对象,而是从MSDN中得知:

"如果此实例和sb具有相等的字符串容量最大容量值,则为True;否则为False。"

你所做的其余检查都是比较引用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接