Как стать автором
Обновить

C#: required

Время на прочтение2 мин
Количество просмотров10K

Некоторые разработчики предпочитают объектную инициализацию использованию конструкторов. Кто-то негодует из-за вынужденного "перекладывания" аргументов из одного конструктора в другой при наследовании. Кому-то конструкторы не нравятся просто как таковые. Но возможна ли жизнь без конструкторов?

 л
л

Если на скриншоте слева копипаст вам еще не кажется адским, представьте что аргументов у базового конструктора больше и MyClassChild тоже есть наследники, которые вынуждено наследуют родительский копипаст.

Object initialization

Простое решение здесь это банально не копипастить, отказаться от конструкторов, сделать сервисы паблик и создавать экземпляры через объектную инициализацию(в фигурных скобочках). Очевидной проблемой такого подхода является потеря каких-либо гарантий того, что мы точно проинициализировали все, что нужно. NullReference будет поджидать вас на каждой инициализации, ведь полное покрытие тестами обычно кажется слишком большой ценой.

Также становится сомнительно использование init в купе с nullable reference types. Дело в том, что мы теряем гарантии того, что init св-во не null:

Record

Records, представленные в C# 9 частично спасают ситуацию, но перекладывать аргументы все еще надо, плюс, не всегда хочется терять мутабельность:

Object initialization + Required

Нам поможет, на текущий момент proposed, фича - Required Members. Члены, обязательные для инициализации помечаются новым ключевым словом required, что дает возможность компилятору проверять, факт инициализации:

error CS9506: Required member 'MyClassNew.Service1' must be set in the object initializer or attribute constructor.

Модификатор допустим для полей и св-в классов, структур и рекордов. "Под капотом", члены типа с requiredа также и сам тип помечаются атрибутом [RequiredMember]. Как не сложно догадаться, есть вагон и маленькая тележка кейсов, в которых новый модификатор конфликтует с уже существующими. Из того, что на поверхности - такое поле нельзя делать недоступным для присвоения извне().

При этом конструкторы, не гарантирующие инициализацию всех required членов типа, принудительно("под капотом") помечаются как нежелательные для использования. В том числе и конструктор по умолчанию:

Заключение

Как и прочие языковые фичи, required должен применяться там, где он упрощает, а не усложняет жизнь, это не "золотая пуля". Лично я немного устал от бесполезных реализаций конструкторов, очень жду момента, когда их можно будет выпилить.

Спецификация. Обсуждение на GitHub.

Теги:
Хабы:
Всего голосов 8: ↑6 и ↓2+4
Комментарии20

Публикации

Истории

Работа

Ближайшие события

27 августа – 7 октября
Премия digital-кейсов «Проксима»
МоскваОнлайн
11 сентября
Митап по BigData от Честного ЗНАКа
Санкт-ПетербургОнлайн
19 сентября
CDI Conf 2024
Москва
24 сентября
Конференция Fin.Bot 2024
МоскваОнлайн
25 сентября
Конференция Yandex Scale 2024
МоскваОнлайн
28 – 29 сентября
Конференция E-CODE
МоскваОнлайн
28 сентября – 5 октября
О! Хакатон
Онлайн
30 сентября – 1 октября
Конференция фронтенд-разработчиков FrontendConf 2024
МоскваОнлайн