Обложка канала

.NET Разработчик

Опытный разработчик не так давно зашёл в .Net и поставил цель получить сертификат Microsoft. Свой ежедневный прогресс он описывает на канале .Net Разработчик. Заметки об изученном материале, советы по повышению производительности и поддержке мотивации, ин

.NET Разработчик

4 года назад
Открыть в
День 1391. #ЗаметкиНаПолях Подробнее об Обязательных Членах Класса в C#11 В C#11 представлено новое ключевое слово required, которое может применяться к полю и свойству класса, записи или структуры.
class Foo {
 internal required int _field;
 internal required int 
  Prop { get; set; }
}

Оно обязывает вызывающий код инициализировать поле или свойство. Если этого не сделать: var foo = new Foo(); мы получим ошибку CS9035: Required member 'Foo._field' must be set in the object initializer or attribute constructor. (Обязательный член 'Foo._field' должен быть задан в инициализаторе объекта или конструктор должен иметь атрибут.) Это очень полезное дополнение для улучшения сценария инициализации объекта, особенно в отношении init-свойств, которые могут быть инициализированы только в конструкторе или в инициализаторе. Ограничения обязательных членов 1. required не может применяться к закрытому члену, поскольку ограничение ключевого слова действует за пределами родительского класса, когда вызывающий объект создаёт его экземпляр. 2. required не может применяться к статическому члену, поскольку оно предназначено для использования только во время создания экземпляра объекта. 3. required не может применяться к члену, доступному только для чтения, который может быть назначен только в конструкторе. Зачем это нужно? Инициализаторы объектов были введены для преодоления некоторых известных ограничений конструктора, вроде необходимости соблюдать порядок параметров, необходимости задавать все параметры, даже которые не нужны, ломающих изменениях, когда в класс добавляется новый член и новый параметр в конструктор и т.п. До сих пор было невозможно требовать, чтобы инициализаторы устанавливали член, что приводило к необходимости использовать конструктор в таком сценарии. Обязательные члены и конструктор Ключевое слово required на самом деле является частью публичного контракта всех конструкторов класса. Компилятор не пытается проверить, присваивается ли значение обязательному члену в самом конструкторе. Если это ваш случай, добавьте атрибут SetsRequiredMembers к конструктору, что сообщит компилятору, что обязательные члены заданы. Обязательные члены и переопределение свойств Есть несколько ограничений при переопределении обязательных свойств: 1. required нельзя использовать интерфейсах и для членов, являющихся явной реализацией интерфейса. 2. При переопределении обязательного виртуального или абстрактного свойства ключевое слово required должно быть указано повторно.
interface IInterface
{
  int Prop { get; init; }
  // ОШИБКА 
  required int Foo { get; init; }
}

abstract class Base
{
  public required abstract int 
   Abstr { get; init; }
  public required virtual int 
   Virt { get; init; }
}

class Derived : Base, IInterface
{
  public int Foo { get; init; }
  // ОШИБКА
  required int IInterface.Prop { get; init; }
  
  // required повторно в переопределениях
  public required override int 
   Abstr { get; init; }
  public required override int
   Virt { get; init; }
}

Источник: https://blog.ndepend.com/c-11-required-members/