У меня есть DTO, который заполняется чтением из таблицы DynamoDB. Скажем, сейчас это выглядит так:
public class Item
{
public string Id { get; set; } // PK so technically cannot be null
public string Name { get; set; } // validation to prevent nulls but this doesn't stop database hacks
public string Description { get; set; } // can be null
}
Есть ли лучшая практика для решения этой проблемы? Я бы предпочел избегать конструктора без параметров, поскольку он плохо работает с ORM в Dynamo SDK (как и с другими).
Мне кажется странным писать, public string Id { get; set; } = "";
потому что это никогда не произойдет, так Id
как это PK и никогда не может быть нулевым. Какая польза будет ""
, даже если это все равно как-нибудь?
Так что лучше в этом деле?
- Должен ли я отметить их всех так,
string?
чтобы они говорили, что они могут быть нулевыми, хотя некоторые никогда не должны быть. - Должен ли я инициализировать
Id
иName
с,""
потому что они никогда не должны быть нулевыми, и это показывает намерение, хотя""
никогда не будет использоваться. - Некоторая комбинация выше
Пожалуйста, обратите внимание: это о C # 8 обнуляемых ссылочных типов. Если вы не знаете, на что лучше всего не отвечать.
c#
c#-8.0
non-nullable
nullable-reference-types
BritishDeveloper
источник
источник
#pragma warning disable CS8618
в верхней части файла.= ""
этого вы можете использовать= null!
для инициализации свойство, которое, как вы знаете, никогда не будет эффективноnull
(когда компилятор не может этого знать). Если этоDescription
может быть юридическиnull
, это должно быть объявленоstring?
. В качестве альтернативы, если проверка обнуляемости для DTO более неприятна, чем справка, вы можете просто обернуть тип в#nullable disable
/,#nullable restore
чтобы отключить NRT только для этого типа.Ответы:
Как вариант, вы можете использовать
default
литерал в сочетании сnull forgiving operator
Поскольку ваш DTO заполняется из DynamoDB, вы можете использовать
MaybeNull/NotNull
атрибуты постусловия для управления обнуляемостьюMaybeNull
Обнуляемое возвращаемое значение может быть нулевым.NotNull
Обнуляемое возвращаемое значение никогда не будет нулевым.Но эти атрибуты влияют только на обнуляемый анализ для тех участников, которые отмечены ими. Обычно эти атрибуты применяются к методам возврата, свойствам и индексаторам.
Таким образом, вы можете считать все ваши свойства ненулевыми и украсить их
MaybeNull
атрибутом, указывающим, что они возвращают возможноеnull
значениеВ следующем примере показано использование обновленного
Item
класса. Как видите, вторая строка не показывает предупреждение, а третья -Или вы можете сделать все свойства обнуляемыми и использовать,
NoNull
чтобы указать, что возвращаемое значение не может бытьnull
(Id
например)Предупреждение будет таким же, как и в предыдущем примере.
Также есть
AllowNull/DisallowNull
атрибуты предусловий для входных параметров, свойств и установщиков индексаторов, работающие аналогичным образом.AllowNull
Необнуляемый входной аргумент может быть нулевым.DisallowNull
Обнуляемый входной аргумент никогда не должен быть нулевым.Я не думаю, что это поможет вам, так как ваш класс заполняется из базы данных, но вы можете использовать их для управления обнуляемостью установщиков свойств, например, для первого варианта
И для второго
Некоторые полезные детали и примеры пост / предварительных условий можно найти в этой статье devblog
источник
Ответ из учебника в этом сценарии - использовать
string?
для вашейId
собственности, но также украсить его[NotNull]
атрибутом:Итак, что именно здесь происходит?
string?
возвращаемый тип не позволяет компилятору предупреждать вас о том, что свойство неинициализировано во время построения, и поэтому будет иметь значение по умолчаниюnull
.[NotNull]
атрибут предотвращает предупреждение при назначении свойства ненулевой переменной или попытке разыменования его, поскольку вы сообщаете статическому анализу потока компилятора, что на практике это свойство никогда не будетnull
.Чтобы помочь вам сохранить это обязательство, вы можете дополнительно добавить аннотацию к свойству
[DisallowNull]
:Это может не относиться к вашему случаю, так как значения присваиваются через базу данных, но
[DisallowNull]
атрибут выдаст вам предупреждение, если вы когда-либо попытаетесь присвоитьnull
(способное) значениеId
, даже если тип возвращаемого значения позволяет ему быть нуль . В этом отношении, онId
будет действовать точно так же, как иstring
в случае статического анализа потоков в C #, и в то же время позволит значению оставаться неинициализированным между созданием объекта и заполнением объекта.источник
String является ссылочным типом и всегда обнуляемым, вам не нужно делать ничего особенного. Проблемы могут возникнуть только позже, если вы хотите отобразить этот тип объекта на другой, но вы можете справиться с этим позже.
источник