Поделиться через


обязательный модификатор (справочник по C#)

Модификатор required указывает, что поле или свойство , к которому он применяется, должно быть инициализировано с помощью инициализатора объекта . Любое выражение, инициализирующее новый экземпляр типа, должно инициализировать все необходимые элементы . Модификатор required доступен начиная с C# 11. Модификатор required позволяет разработчикам создавать типы, в которых свойства или поля должны быть правильно инициализированы, но по-прежнему разрешать инициализацию с помощью инициализаторов объектов. Некоторые правила обеспечивают такое поведение:

  • Модификатор required можно применять к полям и свойствам, объявленным в struct, а также к типам class, включая record и типы record struct. Модификатор required нельзя применять к элементам interface.
  • Явные реализации интерфейса не могут быть помечены как required. Их нельзя задать в инициализаторах объектов.
  • Обязательные элементы должны быть инициализированы, но они могут быть инициализированы в null. Если тип является ссылочным типом, не допускающим значение NULL, компилятор выдает предупреждение при инициализации элемента в null. Компилятор выдает ошибку, если член не инициализирован вообще.
  • Требуемые члены должны быть как минимум столь же видимы, как их содержащий тип. Например, класс public не может содержать поле required с характеристикой protected. Кроме того, обязательные свойства должны иметь методы задания (set или init методы доступа), которые по крайней мере, столь же видимы, как их содержащие типы. Элементы, недоступные для доступа, не могут быть заданы кодом, создающим экземпляр.
  • Производные классы не могут скрыть элемент required, объявленный в базовом классе. Скрытие необходимого элемента запрещает вызывающим объектам использовать инициализаторы объектов для него. Кроме того, производные типы, которые переопределяют необходимое свойство, должны включать модификатор required. Производный тип не может удалить состояние required. Производные типы могут добавлять модификатор required при переопределении свойства.
  • Тип с любыми элементами required не может использоваться в качестве аргумента типа, если параметр типа включает ограничение new(). Компилятор не может гарантировать, что все обязательные элементы инициализированы в генерик-коде.
  • Модификатор required не допускается в объявлении позиционных параметров записи. Можно добавить явное объявление для позиционного свойства, которое включает в себя модификатор required.

Некоторые типы, такие как позиционные записи , используют первичный конструктор для инициализации соответствующих свойств. Если любое из этих свойств включает модификатор required, основной конструктор добавляет атрибут SetsRequiredMembers. Это означает, что основной конструктор инициализирует все необходимые элементы. Вы можете написать собственный конструктор с помощью атрибута System.Diagnostics.CodeAnalysis.SetsRequiredMembersAttribute. Однако компилятор не проверяет, что эти конструкторы инициализируют все требуемые члены. Скорее, атрибут утверждает компилятору, что конструктор инициализирует все необходимые элементы. Атрибут SetsRequiredMembers добавляет эти правила в конструкторы:

  • Конструктор, который объединяется с другим конструктором, аннотированный атрибутом SetsRequiredMembers либо this(), либо base(), также должен включать атрибут SetsRequiredMembers. Это гарантирует правильность использования всех соответствующих конструкторов вызывающими лицами.
  • Конструкторы копирования, созданные для типов record, имеют атрибут SetsRequiredMembers, если любой из членов является required.

Предупреждение

SetsRequiredMembers отключает проверки компилятора, что все элементы required инициализированы при создании объекта. Используйте его с осторожностью.

В следующем коде показана иерархия классов, использующая модификатор required для свойств FirstName и LastName:

public class Person
{
    public Person() { }

    [SetsRequiredMembers]
    public Person(string firstName, string lastName) =>
        (FirstName, LastName) = (firstName, lastName);

    public required string FirstName { get; init; }
    public required string LastName { get; init; }

    public int? Age { get; set; }
}

public class Student : Person
{
    public Student() : base()
    {
    }

    [SetsRequiredMembers]
    public Student(string firstName, string lastName) :
        base(firstName, lastName)
    {
    }

    public double GPA { get; set; }
}

Дополнительные сведения о необходимых членах см. в разделе C#11 — обязательные элементы спецификации компонентов.