Здравствуйте, Разраб, Вы писали:
Р>Или вам норм?
Оба плохо. Если вы не хотите пользоваться nullable annotations — отключите их. А так выглядит, что вы пытаетесь "купить билет и не поехать".
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Что значит проще? Если значение может быть null, значит переменная должна быть объявлена как object?
Если null не может быть, значит переменная object и каких default!
Иначе получится, что функция принимает object, убеждена что там null не может быть, проверок не делает, компилятор ни о каких проблемах не сигнализирует и код успешно падает в рантайме.
Если хочется везде на null проверять, то не нужно и nullable аннотации эти включать и можно писать как 10 лет назад все писали без них.
Вот это чудо "object obj = default!;" выглядит как самостоятельный выстрел в ногу.
Здравствуйте, Разраб, Вы писали:
Р>Подумал тут Р>Уж проще так
Р>
Р>object? obj;
Р>
Р>чем постоянно так Р>
Р>object obj = default!;
Р>
Р>Или вам норм?
Норм. У тебя может быть другой контекст, но у меня типичная ситуация такая:
В процессе инициализации какого-то объекта поля могут быть nullable, но по завершению там гарантированно null не будет.
И тут приходится выбирать из трех стульев
1) Делать два разных типа. Как-то расточительно.
2) Отдавать клиенту объект с nullable-полями, пусть сам ублажает компилятор ставит ненужные проверки или восклицательные знаки.
3) Собственно default!
Был бы конечно не прочь взглянуть на какой-нибудь реальный код где и Nullable анотации есть и восклицательные знаки не используются.
Здравствуйте, Константин Б., Вы писали:
КБ>В процессе инициализации какого-то объекта поля могут быть nullable, но по завершению там гарантированно null не будет. КБ>И тут приходится выбирать из трех стульев
КБ>1) Делать два разных типа. Как-то расточительно. КБ>2) Отдавать клиенту объект с nullable-полями, пусть сам ублажает компилятор ставит ненужные проверки или восклицательные знаки. КБ>3) Собственно default!
Есть ещё стул в виде "Null Object". Например, при поиске индекса элемента в List возвращается -1, а не null. То же самое можно и с объектами делать и создать некие Undefined объекты.
Ну, а если такая сложная сборка объекта происходит, то напрашивается Builder. Или он и подразумевался под пунктом 1?
Кроме null могут быть и другие недопустимые значения и в целом возникают вопросы о том где валидировать значения.
Ну, вот зарплата сотрудника по идее не может быть нулевой или отрицательной, но при создании наверняка по умолчанию будет ноль.
При этом где-то в формулах может быть деление на эту самую зарплату.
В set-тере свойства ставим проверку и кидаем исключения? Тогда опять же как собирать такого сотрудника без Builder'а или ещё какого доп. объекта?
Или разрешаем писать в свойство что угодно, а потом везде проверяем на 0 и отрицательное?
Или не проверяем и надеемся, что нуля там не будет и формирование отчёта не упадёт?
Какой подход принят в проекте относительно других вариантов, логично и для null использовать.
Разница только в том, что null компилятором контролируется и он подсказывает все проблемы, но по-моему для этого C# и берут,
а то можно и на JavaScript писать что попало, чтобы не приставали со своими ошибками времени компиляции.
Здравствуйте, karbofos42, Вы писали:
K>Есть ещё стул в виде "Null Object". Например, при поиске индекса элемента в List возвращается -1, а не null. То же самое можно и с объектами делать и создать некие Undefined объекты.
Это стул номер 2. Клиент будет делать ненужные проверки на NullObject.
Вся суть аннотаций — мы говорим пользователю API где ему *не надо* проверять то что мы вернули.
K>Ну, а если такая сложная сборка объекта происходит, то напрашивается Builder. Или он и подразумевался под пунктом 1?
Нет, подразумевалось просто два класса, один с Nullable полями, другой без. Но билдер в принципе обладает теми же недостатками.
K>Ну, вот зарплата сотрудника по идее не может быть нулевой или отрицательной, но при создании наверняка по умолчанию будет ноль.
Тут как раз все просто и проверка должна быть в рантайм.
Здравствуйте, Константин Б., Вы писали:
КБ>Это стул номер 2. Клиент будет делать ненужные проверки на NullObject. КБ>Вся суть аннотаций — мы говорим пользователю API где ему *не надо* проверять то что мы вернули.
Не будет клиент ничего проверять. Сейчас же у вас специально свойство объявлено как object, а не object? ровно потому, что убеждены, что после инициализации точно null не будет и проверки не нужны.
Вот так же будет на совести разработчика обязательство заменить все NullObject на нормальные объекты или будут те же проблемы, что сейчас из-за default!
Принципиально ничего не изменится, код так и останется костыльным, но зато не будет нужно использовать !
КБ>Нет, подразумевалось просто два класса, один с Nullable полями, другой без. Но билдер в принципе обладает теми же недостатками.
В такой схеме уже будет не 2 класса, а 3 класса, т.к. кто-то должен будет из nullable сделать не nullable.
КБ>Тут как раз все просто и проверка должна быть в рантайм.
Ага. Что-то типа такого будет?
class Company
{
...
}
class Employee
{
private int salary;
public Company Company { get; set; }
public int Salary
{
get => salary;
set
{
if (value <= 0)
throw new Exception();
salary = value;
}
}
public Employee()
{
Company = default!;
}
}
А дальше тайные знания о том, что после создания объектов нужно все свойства инициализировать нормально или в них будет всякий неожиданный хлам, на который никто нигде проверки не делает?
Или как выглядят все эти non-nullable с присвоенным default! ?
Ф>Я пока не ковырял nullable reference types. Ф>object? для меня очень странно выглядит. Я бы не стал так писать.
Это референс который штатно может быть нулевым, то есть его надо каждый раз при использовании проверять, и места где это не делаеться подсвечиваются.
Если без воппросительного знака — то штатно нулем быть не может и проверять не надо вообще, если не инициализировать или присвоить ноль тоже подсветка ругает.
Собственно и вся история, полезная вещь.
Здравствуйте, _NN_, Вы писали:
_NN>Здравствуйте, Константин Б., Вы писали:
_NN>Для таких случаев есть MemberNotNull который скажет после вызова этого метода такое поле не будет null.
_NN>