【问题标题】:What is the difference between .Equals and == [duplicate].Equals 和 == 有什么区别 [重复]
【发布时间】:2009-04-21 14:50:49
【问题描述】:

对于值类型、引用类型和字符串,a.Equals(b)a == b 有什么区别?看起来 a == b 似乎对字符串很有效,但我正在努力确保使用良好的编码实践。

【问题讨论】:

标签: c# .net string


【解决方案1】:

来自When should I use Equals and when should I use ==

Equals 方法只是一个虚拟的 一个在 System.Object 中定义,并且 被选择的任何类覆盖 这样做。 == 运算符是 可以被重载的运算符 类,但通常有 身份行为。

对于 == 没有的引用类型 被重载,它比较是否 两个参考引用相同 对象 - 这正是 Equals 的实施确实在 系统对象。

值类型不提供重载 对于 == 默认情况下。然而,大多数 提供的值类型 框架提供自己的重载。 Equals 的默认实现 对于值类型由提供 ValueType,并使用反射来制作 比较,这使得它 明显慢于 通常特定于类型的实现 将会。这个实现也 对引用对调用 Equals 在被比较的两个值之间。

using System;

public class Test
{
    static void Main()
    {
        // Create two equal but distinct strings
        string a = new string(new char[] {'h', 'e', 'l', 'l', 'o'});
        string b = new string(new char[] {'h', 'e', 'l', 'l', 'o'});

        Console.WriteLine (a==b);
        Console.WriteLine (a.Equals(b));

        // Now let's see what happens with the same tests but
        // with variables of type object
        object c = a;
        object d = b;

        Console.WriteLine (c==d);
        Console.WriteLine (c.Equals(d));
    }
}

这个简短的示例程序的结果是

True
True
False
True

【讨论】:

  • 我可能是错的,但我认为符合 Console.WriteLine (c.Equals(d));这是误导,因为对于引用类型,Equals 将比较引用的值,这很重要。在这里它是 True 只是因为在运行时变量“b”包含字符串实例,并且 String 覆盖了虚拟 Equals(object d) 方法,并且它的逻辑包含字符串精确值逐个字符的比较。在这种情况下,“hello”的字符串值实际上是相同的,但如果输入不同的字符串,将导致 Equals 方法的结果为 False。
【解决方案2】:

Here is a great blog post about WHY the implementations are different.

基本上 == 将在编译时使用变量的类型进行绑定,而 .Equals 将在运行时动态绑定。

【讨论】:

  • Lippert 链接+1,我之前一直在寻找这个!
【解决方案3】:

最简答:

==opertator 是检查身份。(即:a==b 这两个是同一个对象吗?)

.Equals() 是检查值。(即:a.Equals(b) 都持有相同的值?)

有一个例外:
对于string预定义值类型(如intfloat等),
运算符 == 将回答价值而不是身份。 (与使用 .Equals() 相同)

【讨论】:

    【解决方案4】:

    它们之间的一个显着区别是== 是一个静态二元运算符,适用于一个类型的两个实例,而Equals 是一个实例方法。这很重要的原因是您可以这样做:

    Foo foo = new Foo()
    Foo foo2 = null;
    foo2 == foo;
    

    但是如果不抛出NullReferenceException,你就无法做到这一点:

    Foo foo = new Foo()
    Foo foo2 = null;
    foo2.Equals(foo);
    

    【讨论】:

    • 我发现Object.Equals(x,y)不会给NullReferenceException
    【解决方案5】:

    简单来说,区别在于调用的是哪个方法。 == 方法将尝试绑定到 operator== 如果为有问题的类型定义。如果没有找到值类型的 ==,它将进行值比较,而对于引用类型,它将进行引用比较。 .Equals 调用将对 .Equals 方法进行虚拟调度。

    至于具体方法的作用,全在代码中。用户可以定义/覆盖这些方法并做他们想做的任何事情。理想情况下,这些方法应该是等价的(对不起,双关语)并且具有相同的输出,但并非总是如此。

    【讨论】:

    • +1 值得一提的是,Equals 是一种虚拟方法。
    【解决方案6】:

    帮助记住差异的一个简单方法是a.Equals(b) 更类似于
    a == (object)b

    .Equals() 方法不是通用的,它接受类型为“object”的参数,因此在与 == 运算符进行比较时,您必须将其视为好像右手操作数首先被强制转换为 object。

    一个暗示是a.Equals(b) 几乎总是会为ab 返回一些值,而不管类型如何(如果b 是未知类型,则重载的正常方法是只返回false) .如果这些类型没有可用的比较,a == b 只会抛出异常。

    【讨论】:

      【解决方案7】:

      "==" 是一个可以重载的运算符,可以根据被比较的类型执行不同的操作。

      ==”执行的默认操作是a.Equals(b);

      以下是如何为字符串类型重载此运算符:

      public static bool operator == (string str1, string str2) 
      {
          return (str1.Length == str2.Length;)
      }
      

      请注意,这与 str1.Equals(str2); 不同

      派生类也可以覆盖和重新定义Equals()

      就“最佳实践”而言,这取决于您的意图。

      【讨论】:

      • 您能否澄清一下““== 执行的默认操作是 a.Equals(b)”的意思。
      • 如果你不重载 '==' 操作符,它的作用与 Equals() 函数的作用相同。对于字符串,它会进行字符串比较,对于用户类型,它会比较引用。
      【解决方案8】:

      对于字符串,您需要注意特定于文化的比较。经典的例子是德语双 S,看起来有点像 a b。这应该与“ss”匹配,但不是简单的 == 比较。

      对于文化敏感的字符串比较使用: String.Compare(expected, value, StringComparison....) == 0 ?使用您需要的 StringComparison 重载。

      【讨论】:

        【解决方案9】:

        默认情况下,==.Equals() 是等价的,除了在 null 实例上调用 .Equals() 的可能性(这会给你一个 NullReferenceException)。但是,您可以独立地覆盖它们中的任何一个的功能(尽管我不确定这是否是一个好主意,除非您尝试解决另一个系统的缺点),这意味着您可以使它们不同.

        你会在过道的两边找到要使用的人。我更喜欢运算符而不是函数。

        不过,如果您谈论的是字符串,那么使用 string.Compare() 而不是其中任何一个选项可能会更好。

        【讨论】:

          猜你喜欢
          • 2010-12-11
          • 1970-01-01
          • 2011-11-23
          • 2011-12-02
          • 2022-12-04
          • 2017-02-17
          相关资源
          最近更新 更多