System.ValueType.Equals
специально.Он выполняет следующие шаги по порядку, пока не получит некоторый результат:
- Если
obj
по сравнению с 'null', он возвращает false
. - Если
this
и obj
аргументы разных типов, он возвращает false
. - Если тип "blittable", он сравнивает образы памяти.Если они идентичны, возвращается
true
. - Наконец, он использует отражение для вызова
Equals
парных экземпляров полей для каждого значения.Если какое-либо из этих полей не равно, возвращается false
.В противном случае возвращается true
.Обратите внимание, что он никогда не вызывает базовый метод, Object.Equals
.
Поскольку он использует отражение для сравнения полей, вы должны всегда переопределять Equals
на любом ValueType
, который вы создаете.Отражение медленное.
Когда это "GCReference" или поле в структуре, являющееся ссылочным типом, оно заканчивается использованием отражения в каждом поле для сравнения.Это необходимо сделать, потому что struct
на самом деле имеет указатель на расположение ссылочного типа в куче.
Если в структуре нет ссылочного типа, и они имеют одинаковый тип, полягарантированно будут в том же порядке, и будут иметь одинаковый размер в памяти, поэтому он может просто сравнивать пустую память.
Для структуры только с типами значений для полей, т.е. структуры только с одним int
поле, отражение не производится во время сравнения.Ни одно из полей не ссылается на что-либо в куче, поэтому нет GCReference
или GCHandle
.Кроме того, любой экземпляр этой структуры будет иметь одинаковую структуру полей в памяти (с некоторыми небольшими исключениями), поэтому команда CLR может выполнить прямое сравнение памяти (memcmp), которое намного быстрее, чем другой параметр.
Так что да, если в вашей структуре есть только типы значений, он будет выполнять более быстрое memcmp вместо сравнения отражений, но вы можете этого не делать.Продолжайте читать.
Этот не означает, что вы должны использовать реализацию по умолчанию Equals
.На самом деле, не делай этого.Останови это.Он выполняет сравнение битов, которые не всегда точны.Что это вы говорите?Позвольте мне показать вам:
private struct MyThing
{
public float MyFloat;
}
private static void Main(string[] args)
{
MyThing f, s;
f.MyFloat = 0.0f;
s.MyFloat = -0.0f;
Console.WriteLine(f.Equals(s)); // prints False
Console.WriteLine(0.0f == -0.0f); // prints True
}
Числа математически равны, но они не равны в своем двоичном представлении.Итак, еще раз подчеркну, не полагаться на реализацию по умолчанию ValueType.Equals