With-expressions
При работе с immutable данными общим шаблоном является создание новых значений из существующих для представления нового состояния. Например, если бы наш человек изменил свою фамилию, мы представили бы ее как новый объект, который является копией старого, за исключением другой фамилии. Эту технику часто называют неразрушающей мутацией. Вместо того, чтобы представлять человека с течением времени, запись представляет состояние человека в данный момент времени.
Чтобы помочь с этим стилем программирования, записи позволяют новый вид выражения; with-expression :
With-expressions используется синтаксис инициализатора объектов, чтобы указать, что отличается в новом объекте от старого объекта. Можно указать несколько свойств.
Запись неявно определяет protected "конструктор копирования" - конструктор, который берет существующий объект записи и копирует его поле по полю в новый:
Выражение with вызывает конструктор копирования, а затем применяет инициализатор объекта сверху, чтобы соответствующим образом изменить свойства.
Value-based equality
Все объекты наследуют метод virtual Equals (object) от класса object. Это используется в качестве основы для объекта Object.Equals(object, object), когда оба параметра ненулевые.
Структуры переопределяют это, чтобы иметь "value-based equality", сравнивая каждое поле структуры, вызывая Equals рекурсивно. Записи делают то же самое.
Это означает, что в соответствии с их «value-ness» два объекта записи могут быть равны друг другу, не будучи одним и тем же объектом. Например, если мы снова изменим фамилию измененного человека:
Теперь у нас будет ReferenceEquals (person, originalPerson) = false (это не один и тот же объект), но Equals (person, originalPerson) = true (они имеют одинаковое значение).
Если вам не нравится поведение сравнения по полям по умолчанию сгенерированного переопределения Equals, вы можете написать свое собственное. Вам просто нужно быть осторожным, чтобы понять, как в записях работает равенство на основе значений, особенно когда речь идет о наследовании, о чем мы еще вернемся ниже.
Наряду с value-based Equals существует также переопределение GetHashCode (), основанное на значениях.