C# 运算符 ==、StringBuilder.Equals、Object.Equals 和 Object.ReferenceEquals 之间的区别

Posted

技术标签:

【中文标题】C# 运算符 ==、StringBuilder.Equals、Object.Equals 和 Object.ReferenceEquals 之间的区别【英文标题】:C# Differences between operator ==, StringBuilder.Equals, Object.Equals and Object.ReferenceEquals 【发布时间】:2013-04-29 06:42:34 【问题描述】:

我对@9​​87654321@ 和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) 那么为什么它会给出两个不同的结果呢?

【问题讨论】:

你应该想出一个更好的问题标题。电流没有任何意义。请不要在标题中重复标签。 @ReferenceEquals:你是比较四种比较方法。我修改了你的标题以更好地反映你的问题。 为什么要检查 2 个字符串生成器的相等性?这就像检查流或文本编写器是否相等。 【参考方案1】:

你错过了另一个测试:

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

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

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

【讨论】:

重载Equals而不覆盖它。 WTF他们认为。就我个人而言,我会使用引用相等,但这种选择只是令人困惑。 你应该解释一下Object.Equals()IEquatable<T>之间的区别 因为我们有两个不同的引用(对象、实例)并且默认的 Equal(object) 应该首先返回引用比较。 @MatthewWatson - 我不认为 StringBuild 实现了 IEquatable<T>: msdn.microsoft.com/en-us/library/system.text.stringbuilder.aspx @Kobi 是的,虽然它确实有一些与之匹配的东西。奇怪的是他们没有添加接口。可能这将是一个突破性的变化。【参考方案2】:

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

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

有关详细信息,请参阅:

http://msdn.microsoft.com/en-us/library/f37cfeys.aspx http://msdn.microsoft.com/en-us/library/w4hkze5k.aspx http://msdn.microsoft.com/en-us/library/system.object.referenceequals.aspx

【讨论】:

【参考方案3】:

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

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

你正在做的其余检查比较参考。

【讨论】:

以上是关于C# 运算符 ==、StringBuilder.Equals、Object.Equals 和 Object.ReferenceEquals 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

☀️ 学会编程入门必备 C# 最基础知识介绍——变量常量运算符判断循环

PHP 中 C# 的空值合并运算符 (??)

C#中有指数运算符吗?

C# 运算符重载

为啥“as”运算符在 C# 中不使用隐式转换运算符?

C# 中哪个三元运算符最流行和最常用? [关闭]