== или.Равняется()


зачем использовать один над другим?

12 56
c#

12 ответов:

== - это проверка личности. Он вернет true, если два тестируемых объекта на самом деле являются одним и тем же объектом. Equals() выполняет тест на равенство и возвращает true, если два объекта считают себя равными.

тестирование идентичности происходит быстрее, поэтому вы можете использовать его, когда нет необходимости в более дорогих тестах равенства. Например, сравнение с null или пустая строка.

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


указал ниже: некоторые типы, как String или DateTime обеспечить перегрузки для == оператор, который дает ему семантику равенства. Таким образом, точное поведение будет зависеть от типов объектов, которые вы сравниваете.


посмотреть также:

@John Millikin:

указано ниже: некоторые типы значений, такие как DateTime, обеспечивают перегрузки для оператора==>, которые придают ему семантику равенства. Таким образом, точное поведение будет зависеть от типов >объектов, которые вы сравниваете.

разработка:

DateTime реализуется как структура. Все структуры являются потомками системы.ValueType.

Начиная С Системы.Дети ValueType живут в стеке, нет ссылочного указателя в кучу, и, следовательно, нет способа сделать проверку ссылки, вы должны сравнивать объекты только по значению.

все остальные в значительной степени вы охвачены, но у меня есть еще один совет. Время от времени, вы получите кого-то, кто клянется своей жизнью (и тех, кто его близких), что .Equals более эффективен/лучше / лучшая практика или какая-то другая догматическая линия. Я не могу говорить об эффективности (ну, хорошо, в определенных обстоятельствах я могу), но я могу говорить о большой проблеме, которая возникнет:.Equals требуется объект для существования. (Звучит глупо, но это сбивает людей с толку.)

вы не можете сделайте следующее:

StringBuilder sb = null;
if (sb.Equals(null))
{
    // whatever
}

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

(и годы до DailyWTF сообщение, Я действительно работал с кем-то, кто поручено чтобы все проверки равенства были .Equals вместо ==. Даже доказывая его неточность не помогла. Мы просто чертовски уверены, что нарушили все его другие правила, чтобы никакая ссылка, возвращенная из метода или свойства, никогда не была нулевой, и в конце концов это сработало.)

== обычно " идентичность "равна значению"объект a на самом деле является тем же самым объектом в памяти, что и объект b".

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

Если у вас был пресловутый класс Person со свойствами "имя" и "адрес" и вы чтобы использовать этого человека в качестве ключа в хэш-таблице, содержащей дополнительную информацию о них, вам нужно будет реализовать equals() (и hash), чтобы вы могли создать экземпляр человека и использовать его в качестве ключа в хэш-таблице для получения информации.

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

по данным MSDN:

в C# существует два различных вида равенства: равенство ссылок (также известное как идентичность) и равенство значений. Равенство значений-это общепринятое значение равенства: это означает, что два объекта содержат одни и те же значения. Например, два целых числа со значением 2 имеют равенство значений. Равенство ссылок означает, что нет двух объектов для сравнения. Вместо этого есть две ссылки на объекты, и обе они ссылаются к тому же объекту.

...

по умолчанию оператор = = проверяет равенство ссылок, определяя, указывают ли две ссылки на один и тот же объект.

пример состоит в том, что класс DateTime реализует интерфейс IEquatable, который реализует "тип-специфический метод для определения равенства экземпляров.- согласно MSDN.

еще одна вещь, которую следует учитывать: оператор == может быть не вызываемым или может иметь другое значение, если вы получаете доступ к объекту с другого языка. Как правило, лучше иметь альтернативу, которую можно назвать по имени.

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

например string выполняет тест равенства для ==.

также обратите внимание, что семантика оба могут быть комплекс.

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

class ClassName
{
    public bool Equals(ClassName other)
    {
        if (other == null)
        {
            return false;
        }
        else
        {
            //Do your equality test here.
        }
    }

    public override bool Equals(object obj)
    {
        ClassName other = obj as null; //Null and non-ClassName objects will both become null
        if (obj == null)
        {
            return false;
        }
        else
        {
            return Equals(other);
        }
    }

    public bool operator ==(ClassName left, ClassName right)
    {
        if (left == null)
        {
            return right == null;
        }
        else
        {
            return left.Equals(right);
        }
    }

    public bool operator !=(ClassName left, ClassName right)
    {
        if (left == null)
        {
            return right != null;
        }
        else
        {
            return !left.Equals(right);
        }
    }

    public override int GetHashCode()
    {
        //Return something useful here, typically all members shifted or XORed together works
    }
}

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

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

Если вы разбираете (по dotPeek например) объекта, так

public virtual bool Equals(Object obj)

описан как:

// Returns a boolean indicating if the passed in object obj is
// Equal to this.  Equality is defined as object equality for reference
// types and bitwise equality for value types using a loader trick to
// replace Equals with EqualsValue for value types). 
//

Так, это зависит от типа. Например:

        Object o1 = "vvv";
        Object o2 = "vvv";
        bool b = o1.Equals(o2);

        o1 = 555;
        o2 = 555;
        b = o1.Equals(o2);

        o1 = new List<int> { 1, 2, 3 };
        o2 = new List<int> { 1, 2, 3 };
        b = o1.Equals(o2);

первый раз b истинно (равно выполняется для типов значений), второй раз b истинно (равно выполняется для типов значений), третий раз b ложно (равно выполняется для ссылочных типов).

в большинстве случаев они одинаковы, поэтому вы должны использовать == для ясности. В соответствии с руководящими принципами проектирования Microsoft Framework:

" DO убедитесь, что объект.Операторы Equals и equality имеют точно такую же семантику и схожие характеристики производительности." https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/equality-operators

но иногда, кто-то будет переопределять объект.Равные без обеспечения равенства операторы. В этом случае вы должны использовать Equals для проверки равенства значений и объекта.ReferenceEquals для проверки на равенство ссылок.