Каково различие между.Equals и == [дубликат]

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

  • Это делает код более читабельным. Когда мы видим переменную, мы можем узнать, является ли она временной или переменной экземпляра, посмотрев на объявленные временные переменные.
  • Он определяет область действия переменной (поскольку, например, он может быть только в области видимости блока).
  • . Он позволяет лучше завершать код. Реализация компилятора.

39
задан CodeMonkey1313 21 April 2009 в 14:50
поделиться

8 ответов

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

Это относится к категории глупых предупреждений компилятора: вы написали класс так, чтобы 100% экземпляров InIterator реализовали Iterator , но компилятор его не распознает. (Я полагаю, это зависит от компилятора. Я не вижу предупреждения в моем компиляторе Eclipse, но я знаю, что компилятор Eclipse обрабатывает генерики немного по-другому, чем компилятор JDK.)

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

Для ссылочных типов, где == не имеет был перегружен, сравнивает ли две ссылки относятся к одному и тому же объект - это именно то, что Реализация Равных делает в 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'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
37
ответ дан 27 November 2019 в 02:29
поделиться

Вот отличный пост в блоге о ПОЧЕМУ реализации отличаются .

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

12
ответ дан 27 November 2019 в 02:29
поделиться

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

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

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

Foo foo = new Foo()
Foo foo2 = null;
foo2.Equals(foo);
8
ответ дан 27 November 2019 в 02:29
поделиться

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

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

7
ответ дан 27 November 2019 в 02:29
поделиться

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

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

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

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

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

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

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

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

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

4
ответ дан 27 November 2019 в 02:29
поделиться

"==" is an operator that can be overloaded to perform different things based on the types being compared.

The default operation performed by "==" is a.Equals(b);

Here's how you could overload this operator for string types:

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

Note that this is different than str1.Equals(str2);

Derived classes can also override and redefine Equals().

As far as "best practices" go, it depends on your intent.

0
ответ дан 27 November 2019 в 02:29
поделиться

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

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

0
ответ дан 27 November 2019 в 02:29
поделиться

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

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

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

0
ответ дан 27 November 2019 в 02:29
поделиться
Другие вопросы по тегам:

Похожие вопросы: