- PVSM.RU - https://www.pvsm.ru -
Экземпляры структур [5], в силу своей природы, всегда сравниваются по значению.
Для предопределенных типов, таких как Boolean [7] или Int32 [8], под сравнением по значению понимается сравнение непосредственно значений экземпляров структур.
Если структура определена разработчиком — пользователем платформы, то сравнение по умолчанию автоматически реализуется как сравнение значений полей экземпляров структур.
(Подробности см. в описании метода ValueType.Equals(Object) [9] и операторов == [10] и != [11])
Также при этом автоматически определенным образом реализуется метод ValueType.GetHashCode() [12], перекрывающий метод Object.GetHashCode() [13].
При сравнении значений полей используется рефлексия, что влияет на производительность.
Поле структуры может иметь не "значимый" [6], а ссылочный [3] тип, а в этом случае сравнение полей по ссылке может не подойти с предметной (доменной) точки зрения, и может потребоваться сравнение полей по значению (хотя в общем случае использование в структуре ссылочный полей можно считать неверным архитектурным решением).
(В документации [9] рекомендуется создать для такой структуры собственную реализацию сравнения по значению для повышения производительности и наиболее точного отражения значения равенства для данного типа.)
Может оказаться, что с предметной точки зрения не все поля должны участвовать в сравнении (хотя, опять же, для структур в общем случае это можно считать неверным решением).
С третьей стороны, возможен и особый случай, когда есть "простая" структура, состоящая, например, только из полей-структур, для которых побайтовое сравнение с помощью рефлексии заведомо дает сементически верный результат (например, Int32 [8]).
В этом случае возможно реализовать GetHashCode() корректным образом (чтобы для равных объектов хеш-код всегда был один и тот же), не создавая при этом собственную реализацию сравнения по значению.
Например:
public struct Point
{
private int x;
private int y;
public int X {
get { return x; }
set { x = value; }
}
public int Y
{
get { return y; }
set { y = value; }
}
public override int GetHashCode() => x.GetHashCode() ^ y.GetHashCode();
}
Однако, в случае переписывания этого простого примера с использованием "автосвойств" [15] картина выглядит уже менее ясной:
public struct Point
{
public int X { get; set; }
public int Y { get; set; }
public override int GetHashCode() => X.GetHashCode() ^ Y.GetHashCode();
}
В документации к автосвойствам [15] говорится об автоматическом создании anonymous backing field, соответствующим публичным свойствам.
Строго говоря, из описания неясно, будут ли равными с точки зрения дефолтной реализации сравнения по значению два объекта Point с попарно одинаковыми значениями X и Y:
Скорее всего, где-то в недрах документации или книгах авторов, имеющих отношение к разработке платформы, можно найти положительные ответы на эти вопросы — в том смысле, что поведение для структур с явно объявленными полями и структур с автосвойствами будет давать одинаковый результат при дефолтном сравнении по значению.
Либо, если какая-то часть окажется недокументированной, то, скорее всего, поведение компилятора и исполняющей среды окажется ожидаемым.
Автор: sand14
Источник [16]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/c-2/230832
Ссылки в тексте:
[1] предыдущей публикации: https://habrahabr.ru/post/315258/
[2] классов: https://msdn.microsoft.com/library/0b0thckt.aspx
[3] ссылочными типами — Reference Types: https://msdn.microsoft.com/library/490f96s2.aspx
[4] .NET: https://www.microsoft.com/net
[5] структур: https://msdn.microsoft.com/library/ah19swz4.aspx
[6] "типами по значению" — Value Types: https://msdn.microsoft.com/library/s1ax56ch.aspx
[7] Boolean: https://msdn.microsoft.com/library/system.boolean.aspx
[8] Int32: https://msdn.microsoft.com/library/system.int32.aspx
[9] ValueType.Equals(Object): https://msdn.microsoft.com/library/2dts52z7.aspx
[10] ==: https://msdn.microsoft.com/library/53k8ybth.aspx
[11] !=: https://msdn.microsoft.com/library/3tz250sf.aspx
[12] ValueType.GetHashCode(): https://msdn.microsoft.com/library/system.valuetype.gethashcode.aspx
[13] Object.GetHashCode(): https://msdn.microsoft.com/library/system.object.gethashcode.aspx
[14] первой публикации: https://habrahabr.ru/post/314328/
[15] "автосвойств": https://msdn.microsoft.com/library/bb384054.aspx
[16] Источник: https://habrahabr.ru/post/315622/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.