2008-09-22 6 views
48

Итак, когда я был сравнительным новичком для новичка, которого я сейчас вижу, я думал, что эти две вещи были синтаксическим сахаром друг для друга, то есть, используя один над другим был просто личным предпочтением. Со временем я пришел к выводу, что эти два не то же самое, даже в реализации по умолчанию (см. this и this). Чтобы еще больше смутить вопрос, каждый из них может быть переопределен/перегружен отдельно, чтобы иметь совершенно разные значения.== vs. Object.Equals (object) в .NET

Это хорошая вещь, каковы различия, и когда/почему вы должны использовать один над другим?

ответ

17

MSDN имеет четкие и твердые описания обеих вещей.

object.Equals method

operator ==

Overloadable Operators

Guidelines for Overriding Equals() and Operator ==

Это хорошая вещь, каковы различия, и когда/почему вы должны использовать один над другим ?

Как это может быть «хорошо» или «плохо»? Один - метод, другой - оператор. Если ссылочного равенства недостаточно, перегрузите их, иначе оставьте их как есть. Для примитивных типов они просто работают из коробки.

+0

Как кто-то попадает в дженерики, различия могут быть огромными, когда вы вызываете их на любом типе T слепо. – 2008-09-22 00:26:59

+2

«Слепо» - это плохая практика для всего. если вы знаете ответ на свой вопрос, зачем спрашивать? – aku 2008-09-22 00:28:27

+0

Даже если бы я знал конкретный ответ (чего у меня нет), возможно, по той же причине люди задают вопросы и сами отвечают? Кроме того, как вы можете сделать что-либо еще для универсального типа T? Если вы начинаете делать такие вещи, как if (typeof (T) == typeof (int)), в чем смысл? – 2008-09-22 00:31:45

1

Мое понимание использования обоих заключается в следующем: use == для концептуального равенства (в контексте, эти два аргумента означают одно и то же?) И .Equals для конкретного равенства (эти два аргумента на самом деле точно такой же объект?).

Edit: связанные статьи Кевин Шеффилд делает лучшую работу по разъяснению значения против эталонного равенства ...

+0

Согласен, но это звучит как хорошее эмпирическое правило. – 2010-02-15 22:10:32

+0

Неправильно. `ReferenceEquals` является тестом` identity` в .Net. Если `Equals` всегда выполнял проверку идентичности, тогда не было бы смысла иметь и то, и другое ... – ToolmakerSteve 2014-05-08 22:42:59

0

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

33
string x = "hello"; 
string y = String.Copy(x); 
string z = "hello"; 

Чтобы проверить, если x указывает на тот же объект, как y:

(object)x == (object)y // false 
x.ReferenceEquals(y) // false 
x.ReferenceEquals(z) // true (because x and z are both constants they 
         //  will point to the same location in memory) 

Для того, чтобы проверить, если x имеет то же значение строки как y:

x == y  // true 
x == z  // true 
x.Equals(y) // true 
y == "hello" // true 

Заметим, что это отличается к Java. В Java оператор == не перегружен, поэтому общая ошибка в Java является:

y == "hello" // false (y is not the same object as "hello") 

Для сравнения строк в Java вы должны всегда использовать .equals()

y.equals("hello") // true 
-1

Два из наиболее часто используемых типов, String и Int32, реализуют оба оператора ==() и Equals() как значение равенства (вместо ссылочного равенства).Я думаю, что можно рассмотреть эти два , определяющие примеры, поэтому я пришел к выводу, что оба имеют одинаковые значения. Если Microsoft states otherwise, я думаю, что они намеренно вызывают путаницу.

9

Учитывая текущее заявление Microsoft о операторов равенства == и !=, вывод: ==должен быть просто синтаксический сахар для Object.Equals():

УБЕДИТЕСЬ, что Object.Equals и операторы равенства имеют точно такой же семантика

из http://msdn.microsoft.com/en-us/library/vstudio/7h9bszxx(v=vs.110).aspx

То, что они отличные, а не только сахар, задним числом, кажется Ошибка в их дизайне.

Если вы хотите быть уверены, что получаете IDENTITY сравнение (при сравнении ссылок), тогда используйте ReferenceEquals.

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

ИМХО, было бы лучше, если бы люди не реализовали == и != вообще. Просто дайте .Net по умолчанию Equals и ! Equals, а затем примените Equals.

Если у кого-то разные рассуждения, я бы хотел его услышать.

(И да, это действительно запутанно, учитывая, что Java существовала в первую очередь и использует ==, что означает ReferenceEquals.Но уже слишком поздно изменять .Net вести себя таким образом. И у нас есть собственное заявление Microsoft об этом, в приведенной выше ссылке.)

-1

Оператор == и Equals() оба одинаковы, а мы сравниваем значения вместо ссылок. Вывод обоих параметров аналогичен приведенному ниже примеру.

Пример

static void Main() 
    { 
     string x = " hello"; 
     string y = " hello"; 
     string z = string.Copy(x); 
     if (x == y) 
     { 
      Console.WriteLine("== Operator"); 
     } 
     if(x.Equals(y)) 
     { 
      Console.WriteLine("Equals() Function Call"); 
     } 
     if (x == z) 
     { 
      Console.WriteLine("== Operator while coping a string to another."); 
     } 
     if (x.Equals(y)) 
     { 
      Console.WriteLine("Equals() Function Call while coping a string to another."); 
     } 
    } 

Выход:

== Operator 
    Equals() Function Call 
    == Operator while coping a string to another. 
    Equals() Function Call while coping a string to another. 
3

Я собирался опубликовать это как комментарий к принятому ответ, но я думаю, что это заслуживает того, чтобы учитывать при определении того, какие маршрут.

dotnetfiddle: https://dotnetfiddle.net/gESLzO

код Fiddle:

Object a = null; 
    Object b = new Object(); 

    // Ex 1 
    Console.WriteLine(a == b); 
    // Ex 2 
    Console.WriteLine(b == a); 

    // Ex 3  
    Console.WriteLine(b.Equals(a)); 
    // Ex 4 
    Console.WriteLine(a.Equals(b)); 

Первые 3 примера WriteLine будет работать, но четвёртым бросает исключение.1 и 2 используют ==, который является статическим методом, который не требует создания какого-либо объекта.

Пример 3 работает, потому что создается экземпляр объекта b.

Пример 4 невозможен, поскольку a - null, и поэтому метод не может быть вызван нулевым объектом.

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

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