Comments 15
Requiredиспользуем для строк. Но есть нюанс (*).
Это не нюанс, это нюансище. Чтоб опущенный параметр для всяких Int или Guid выкидывал ошибку валидации, а не инициализировался "по умолчанию".
Будьте внимательны в использовании слова
requiredгде бы то ни было в проекте
Мы в конце концов практически отказались от него. Хлопот больше, чем реальной пользы.
Для других типов я предпочитаю использовать более конкретные атрибуты, вроде Range или прочие самописные (например, IsPositive). А для более сложных валидаций пишу валидаторы, которые заполняют ModelState ошибками.
А мы наоборот, используем в своих DTO его по максимуму. Польза: мы всегда уверены, что все нужные поля будут проинициализировано любым пользователем DTO. Хлопот никаких нет. А какие они у вас?
В своих проектах всё, что можно провалидировать атрибутами, валидирую атрибутами. От этого особенно выигрывают проекты на Blazor, т.к. там это работает, как на сервере, так и на клиенте.
required в DTO даже не думали. У нас вся валидация через атрибуты. (DTO используется только API на базе ASP.NET). Интересно, если required поле не было в приходящем json объекте, ASP.NET возвращает такой же 400 bad request с пропущенным полем, как и с [Required] атрибутом?
Хлопоты, про которые я говорил - накладываемые ограничения, типа конструктора без параметров. Мы хотели убрать null! инициализацию для not nullable properties, но оказались не готовы для этого менять логику.
Все еще непонятно, причем тут какая-то валидация. Ключевое слово required вообще с ней никак не связано.
Хлопоты, про которые я говорил - накладываемые ограничения, типа конструктора без параметров.
Но ведь с required конструктор всё еще запросто может быть без параметров. Что я не так понял в вашем сообщении?
Мы хотели убрать
null!инициализацию для not nullable properties, но оказались не готовы для этого менять логику.
Снова непонятно. Вы осознанно поощряете отсутствие инициализации некоторых полей, но введение required, которое вам бы прогарантировало исправление данной ситуации, вы называете "не готовы менять логику" — т.е. по факту не готовы вручную проинициализировать все пропущенные поля, и сиё утверждение считаете достаточным аргументом против required? Всё так понял, или я снова затупил?
Все еще непонятно, причем тут какая-то валидация. Ключевое слово
requiredвообще с ней никак не связано.
Про валидацию, - потому, что речь о DTO. Проверка атрибута [required] - часть процесса валидации. Смысл там такой же, как и у ключевого слова required - убедиться, что клиент предоставит значение для обозначенного поля. Но атрибут более стандартный, поэтому для нашего ASP.NET API мы использовали его.
Но ведь с
requiredконструктор всё еще запросто может быть без параметров. Что я не так понял в вашем сообщении?Снова непонятно. Вы осознанно поощряете отсутствие инициализации некоторых полей, но введение
required, которое вам бы прогарантировало исправление данной ситуации, вы называете "не готовы менять логику" — т.е. по факту не готовы вручную проинициализировать все пропущенные поля, и сиё утверждение считаете достаточным аргументом противrequired? Всё так понял, или я снова затупил?
вы так эмоционально не понимаете, будто я вас убеждаю отказаться от использования required в вашем коде.
Когда это ключевое слово ввели, у нас было уже написано очень много кода и все классы, где поля обязаны инициализироваться клиентом имели соответствующие конструкторы. Была мысль использовать его шире, убрав инициализацию в null not nullable fields and properties, но это требовало менять инициализацию в куче мест. И да, для нас это было достаточным аргументом не внедрять эту фичу языка в существующий проект.
Простите, но мне стало еще непонятнее.
Во-первых, валидация с атрибутом [Required] абсолютно никак не связаны с ключевым словом required. У них разные предназначения.
"убедиться, что клиент предоставит значение для обозначенного поля" - это ближе к атрибуту. А ключевое слово нужно исключительно при создании экземпляров класса, причем именно через new. (Поддержка разными десериализаторами этого ключевого слова и соответствующее [Required]-like поведение является исключительно следствием появления самого required, но никак не наоборот).
вы так эмоционально не понимаете, будто я вас убеждаю отказаться от использования
У меня скорее складывается подозрение, что у вас ошибочное представление о том, что такое required и зачем он нужен.
Была мысль использовать его шире, убрав инициализацию в
nullnot nullable fields and properties, но это требовало менять инициализацию в куче мест.
Вот например здесь. Если вы действительно хотели ввести ключевое слово required, то, во-первых, вам не понадобилось бы никаких null, а, во-вторых, его легко ввести во все нужные поля даже при наличии существующих конструкторов. И даже на этом этапе от него уже пойдёт определённая польза!
Поэтому либо у вас сильно искажено понимание этого ключевого слова, либо мы вообще говорим о разных языках программирования.
У меня скорее складывается подозрение, что у вас ошибочное представление о том, что такое
requiredи зачем он нужен.
В новых проектах, возможно, контракты на обязательность (кроме DTO) будут через required. А может быть так и останемся во тьме конструкторов с параметрами и прочими фабриками вместо продвинутого ключевого слова. "There are different ways to skin a cat", как говорит мой коллега.
Либо required, либо nullable.
Громко не соглашусь. Вы вот в своей статье почему-то даже не написали для чего, собственно, нужно это ключевое слово. Только как оно работает. Вы также не обосновали это ваше утверждение, хотя оно мелькнуло минимум дважды за статью.
А я вот поделюсь своим личным мнением, для чего оно нужно. На мой взгляд, его единственная цель - это не дать забыть про инициализацию этого поля разработчиком, который пишет new().
В этом случае как тип, так и nullability поля не имеет значения. На разработчика накладывается обязательство explicitly (-over implicitly) указать изначальное значение, даже если оно null/default.
Таким образом чтение кода сильно упрощается - в будущем любому читающему не будет непонятно, писатель кода забыл указать значение, или же оно там действительно должно быть проинициализировано значением "null".
Я не вижу ни одного реального примера, для которого может понадобиться обязательно указывать null для nullable. Допустим, сделали неявное явным, но как это поможет? На мой взгляд это лишь загромождает код. Если в дальнейшем коде устраивает значение по умолчанию, то модификатор required не нужен.
+1
Nullability — это про область определения/множество допустимых значений. То, что null в этом случае соответствует значению по умолчанию не более чем нюанс (иногда, кстати, очень досадный).
required — про явную инициализацию
Понятия ортогональные.
Required. Что скрыто в этом слове?