2009-04-21 2 views
37

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

+0

Посмотрите на http://stackoverflow.com/questions/144530/-or-equals –

ответ

34

От When should I use Equals and when should I use ==:

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

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

Типы значений не обеспечивают перегрузку для == по умолчанию. Однако большинство из типов значений, обеспечиваемых картой , обеспечивают их собственную перегрузку. Реализация по умолчанию Равно для типа значения обеспечивается 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'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 
0

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

операция по умолчанию выполняется «==» является a.Equals(b);

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

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

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

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

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

+0

Не могли бы вы уточнить, что означает «по умолчанию», выполняемое командой «== "является a.Equals (b)". –

+0

Если вы не перегружаете оператор '==', он выполняет ту же функцию, что и функция Equals(). Для строк это сравнение строк, для типов пользователей оно сравнивает ссылки. –

7

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

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

+0

+1 Хорошо отметить, что Equals - это виртуальный метод. –

7

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

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

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

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

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

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

0

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

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

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

11

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

По существу == будет привязан во время компиляции с использованием типов переменных и .Equals будет динамически привязываться во время выполнения.

+0

+1 для ссылки Lippert, я искал это раньше! –

3

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

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

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

6

В самом сокращенном ответ:

== opertator является проверка идентичности. (т. Е. A == b эти два объекта - один и тот же объект?)

.Equals() - проверить значение. (то есть: a.equals (б) и удерживая одинаковые значения?)

За одним исключением:
Для строки и типов предварительно определенное значение (таких как Int, флоат и т.д. ..),
Оператор == ответит за значение, а не за идентификатор. (то же, что и использование .Equals())

Смежные вопросы