== или .Equals()
Зачем использовать один над другим?
Ответы
Ответ 1
== - это тест идентичности. Он вернет true, если два тестируемых объекта фактически являются одним и тем же объектом. Equals()
выполняет тест равенства и возвращает true, если оба объекта считают себя равными.
Идентификация выполняется быстрее, поэтому вы можете использовать ее, когда нет необходимости в более дорогих тестах на равенство. Например, сравнивая с null
или пустой строкой.
Можно перегрузить любой из них, чтобы обеспечить различное поведение - например, тестирование идентификации для Equals()
-, но для того, чтобы кто-либо читал ваш код, не делайте этого.
Указано ниже: некоторые типы, такие как String
или DateTime
, обеспечивают перегрузки для оператора ==
, которые дают ему семантику равенства. Точное поведение будет зависеть от типов объектов, которые вы сравниваете.
См. также:
Ответ 2
@Джон Милликин:
Указано ниже: некоторые типы значений, такие как DateTime, предоставляют перегрузки для оператора ==, которые дают ему семантику равенства. Точное поведение будет зависеть от типов объектов, которые вы сравниваете.
Разработать:
DateTime реализуется как структура. Все структуры являются дочерними элементами System.ValueType.
Так как дети System.ValueType живут в стеке, нет указателя ссылки на кучу и, следовательно, нет способа выполнить контрольную проверку, вы должны сравнивать объекты только по значению.
System.ValueType переопределяет .Equals() и == для использования проверки равенства на основе отражения, он использует отражение для сравнения каждого значения полей.
Поскольку отражение происходит несколько медленно, если вы реализуете свою собственную структуру, важно переопределить .Equals() и добавить свой собственный код проверки значения, поскольку это будет намного быстрее. Не просто вызвать base.Equals();
Ответ 3
Всем, кто в значительной степени затронул вас, но у меня есть еще одно слово совета. Время от времени вы получаете кого-то, кто клянется в своей жизни (и своих близких), что. Эвкалы более эффективны/лучше/лучше всего или в какой-то другой догматической линии. Я не могу говорить об эффективности (хорошо, хорошо, в определенных обстоятельствах я могу), но я могу поговорить с большой проблемой, которая возникнет:.Equals требует существования объекта. (Звучит глупо, но это отбрасывает людей.)
Вы не можете сделать следующее:
StringBuilder sb = null;
if (sb.Equals(null))
{
// whatever
}
Мне кажется очевидным и, возможно, большинством людей, что вы получите исключение NullReferenceException. Однако сторонники Эвальского языка забывают об этом маленьком фактоиде. Некоторые даже "отбрасываются" (извините, не могут удержаться), когда они видят, что NullRefs начинают всплывать.
(И за несколько лет до публикации DailyWTF я действительно работал с кем-то, у кого mandated, что все равенство проверки будут .Equals вместо ==. Даже доказательство его неточности не помогло. Мы просто потрудились нарушить все его другие правила, чтобы никакая ссылка, возвращаемая методом или свойством, никогда не была нулевой, и это сработало в конце.)
Ответ 4
==, как правило, "идентичность" равна значению "объект a на самом деле является тем же самым объектом в памяти, что и объект b".
equals() означает, что объекты логически равны (скажем, с бизнес-точки зрения). Поэтому, если вы сравниваете экземпляры определенного пользователем класса, вам обычно нужно использовать и определять equals(), если вы хотите, чтобы такие вещи, как Hashtable, работали правильно.
Если у вас был класс пословиц Person со свойствами "Имя" и "Адрес", и вы хотели использовать этого Лица в качестве ключа в Hashtable, содержащем больше информации о них, вам нужно будет реализовать equals() (и хэш) так что вы можете создать экземпляр Person и использовать его в качестве ключа в Hashtable для получения информации.
Используя только один, ваш новый экземпляр не будет таким же.
Ответ 5
Согласно MSDN:
В С# существуют два разных типа равенства: ссылочное равенство (также известное как идентификация) и равенство значений. Ценностное равенство - это общепринятое значение равенства: это означает, что два объекта содержат одни и те же значения. Например, два целых числа со значением 2 имеют значение равенства. Ссылочное равенство означает, что не существует двух объектов для сравнения. Вместо этого есть две ссылки на объекты, и оба они относятся к одному и тому же объекту.
...
По умолчанию оператор == проверяет ссылочное равенство, определяя, указывают ли две ссылки на один и тот же объект.
Ответ 6
Пример состоит в том, что класс DateTime реализует интерфейс IEquatable, который реализует "специфичный для типа метод определения равенства экземпляров". согласно MSDN.
Ответ 7
Еще одна вещь, которую следует учитывать: оператор == может не быть вызываемым или может иметь другое значение, если вы обращаетесь к объекту с другого языка. Обычно лучше иметь альтернативу, которая может быть вызвана по имени.
Ответ 8
Оба Equals
и ==
могут быть перегружены, поэтому точные результаты вызова одного или другого будут различаться. Обратите внимание, что ==
определяется во время компиляции, поэтому, хотя фактическая реализация может измениться, которая используется ==
, фиксируется во время компиляции, в отличие от Equals
, которая может использовать другую реализацию на основе типа времени выполнения левой сторона.
Например, string
выполняет проверку равенства для ==
.
Также обратите внимание, что семантика обоих может быть complex.
Лучшей практикой является реализация равенства, подобного этому примеру. Обратите внимание, что вы можете упростить или исключить все это в зависимости от того, как вы планируете использовать свой класс, и что struct
получить большую часть этого уже.
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
}
}
Ответ 9
используйте equals, если вы хотите выразить содержимое сравниваемых объектов, должны быть равны. используйте == для примитивных значений или если вы хотите проверить, что сравниваемые объекты - это один и тот же объект. Для объектов == проверяет, является ли адресный указатель объектов одинаковым.
Ответ 10
Я видел Object.ReferenceEquals(), используемый в случаях, когда нужно знать, ссылаются ли на две ссылки на один и тот же объект
Ответ 11
Если вы разбираете (например, с помощью 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 является ложным (равным для ссылочных типов).
Ответ 12
В большинстве случаев они одинаковы, поэтому для ясности следует использовать ==. В соответствии с Руководством по дизайну Microsoft Framework:
" DO убедитесь, что Object.Equals и операторы равенства имеют точно такую же семантику и аналогичные характеристики производительности."
https://docs.microsoft.com/en-us/dotnet/standard/design-guidelines/equality-operators
Но иногда кто-то переопределяет Object.Equals без предоставления операторов равенства. В этом случае вы должны использовать Equals для проверки равенства значений и Object.ReferenceEquals для проверки ссылочного равенства.
Ответ 13
Я думаю, что фундаментальная путаница вызвана виртуальным методом Equals в System.Object реализована "неправильно"! Он предназначен для проверки равенства, но то, что он делает, это проверка личности.
В библиотеке классов рамки С# (FCL) Equals в классе Object реализуется следующим образом
public virtual bool Equals(object obj)
{
if (this == obj)
{
return true;
}
return false;
}
Таким образом, это обречено на неудачу в иерархии наследования, потому что оно просто проверяет идентичность, а не равенство, что и должно делать. Кроме того, если вы не переопределяете Equals в своем собственном типе, нет никакой разницы между вызовом Equals()
и == (конечно, для сравнения не передайте значение null). Следовательно, он рекламируется, чтобы переопределить Equals в вашем собственном типе и, кроме того, он рекламируется для реализации Equals method from System.IEquatable<T>
для проверки безопасности безопасности типа.