В чем разница между .Equals и ==

В чем разница между a.Equals(b) и a == b для типов значений, типов ссылок и строк? Казалось бы, что == b отлично работает для строк, но я стараюсь использовать хорошие методы кодирования.

Ответы

Ответ 1

Из Когда следует использовать Equals и когда следует использовать ==:

Метод Equals - это просто виртуальный один, определенный в System.Object, и переопределяется тем, какие классы выбирают для этого. Оператор == является оператора, который может быть перегружен классов, но обычно идентичность.

Для ссылочных типов, где == не был перегружен, он сравнивает, две ссылки относятся к тому же объект - это именно то, что реализация Equals в System.Object.

Типы значений не обеспечивают перегрузки для == по умолчанию. Однако большинство типы значений, предоставляемые рамки обеспечивают их собственную перегрузку. Стандартная реализация Equals для типа значения обеспечивается ValueType, и использует отражение, чтобы сделать сравнение, которое делает это значительно медленнее, чем типичная реализация было бы. Эта реализация также вызывает равные по парам ссылок в пределах двух сравниваемых значений.

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 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

Ответ 3

На простом уровне различие заключается в том, какой метод вызывается. Метод == будет пытаться связываться с оператором ==, если он определен для рассматриваемых типов. Если для типов значений найдено value == ==, оно будет выполнять сравнение значений и для ссылочных типов оно будет выполнять сравнительное сравнение. A.Equals вызовет виртуальную отправку по методу .Equals.

Что касается конкретных методов, все это в коде. Пользователи могут определять/переопределять эти методы и делать все, что угодно. В идеале эти методы должны быть эквивалентными (извините за каламбур) и иметь один и тот же результат, но это не всегда так.

Ответ 4

Одно существенное различие между ними заключается в том, что == является статическим двоичным оператором, который работает с двумя экземплярами типа, тогда как Equals является методом экземпляра. Причина в том, что вы можете это сделать:

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

Но вы не можете сделать это, не выбрасывая NullReferenceException:

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

Ответ 5

В наиболее коротком ответе:

== Оператор должен проверить идентификатор. (i.e: a == b - эти два являются одним и тем же объектом?)

.Equals() - проверить значение. (т.е. a.Equals(b) оба имеют одинаковые значения?)

За одним исключением: Для строковых и предопределенных типов значений (таких как int, float и т.д.),
оператор == будет отвечать за значение, а не за идентификатор. (аналогично использованию .Equals())

Ответ 6

Один простой способ помочь запомнить разницу заключается в том, что a.Equals(b) более похож на   a == (object)b.

Метод .Equals() не является общим и принимает аргумент типа "объект", поэтому при сравнении с оператором == вы должны думать об этом, как если бы правый операнд был сначала перенесен в объект.

Одним из следствий является то, что a.Equals(b) почти всегда будет возвращать некоторое значение для a и b, независимо от типа (обычный способ перегрузки - просто вернуть false, если b - тип unkown), a == b просто выбросит исключение, если для этих типов нет сравнения.

Ответ 7

"==" - это оператор, который может быть перегружен для выполнения разных действий на основе сравниваемых типов.

Операция по умолчанию, выполняемая с помощью "==", составляет a.Equals(b);

Здесь вы можете перегрузить этот оператор для типов строк:

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

Обратите внимание, что это отличается от str1.Equals(str2);

Производные классы также могут переопределять и переопределять Equals().

Что касается "лучших практик", это зависит от ваших намерений.

Ответ 8

Для строк вы хотите быть осторожными с сопоставлениями, связанными с культурой. Классическим примером является немецкий двойной S, который немного похож на b. Это должно совпадать с "ss", но не в простом сопоставлении ==.

Для сравнения строк, чувствительных к культуре, используется: String.Compare(ожидается, значение, StringComparison....) == 0? с перегрузкой StringComparison.

Ответ 9

По умолчанию оба == и .Equals() эквивалентны, кроме возможности вызова .Equals() на экземпляр null (который даст вам NullReferenceException). Однако вы можете переопределить функциональность любого из них независимо (хотя я не уверен, что это была бы хорошая идея, если вы не будете пытаться обойти недостатки другой системы), что означало бы, что вы могли бы сделать их разными.

По обеим сторонам прохода вы найдете людей, которые будут использовать. Я предпочитаю оператор, а не функцию.

Если вы говорите о строках, скорее всего, лучше использовать string.Compare() вместо одного из этих параметров.