День сорок четвёртый. #TipsAndTricks
3. Оператор безопасной навигации
Вас ведь тоже бесит постоянно возникающее
Однако в C#6 появился другой способ обойти эту ошибку. Допустим, у вас есть база данных людей, и вы хотите получить данные о трудоустройстве человека, но такие данные отсутствуют, а вы хотите получить название компании-работодателя:
Этот код будет переходить к следующему элементу в цепочке, только если предыдущий не
Источник: https://www.pluralsight.com/guides/tips-for-writing-better-c-code
3. Оператор безопасной навигации
Вас ведь тоже бесит постоянно возникающее
NullReferenceException
, когда происходит обращение к неинициализированному объекту? Чаще всего null-исключение возникает из-за примерно следующего кода:string name = null;В большинстве случаев компилятор не позволит вам продолжить, пока вы не исправите код. Но если вы каким-то образом заставите компилятор думать, что переменная имеет значение, а во время выполнения его не окажется, будет выброшено
Console.WriteLine(name);
NullReferenceException
. Чтобы избежать этого, вы можете сделать следующее:string name = null;Это безопасная проверка, которая позволяет убедиться, что значение переменной доступно при её вызове.
// Некоторый код
if(name != null) {
Console.WriteLine(name);
}
Однако в C#6 появился другой способ обойти эту ошибку. Допустим, у вас есть база данных людей, и вы хотите получить данные о трудоустройстве человека, но такие данные отсутствуют, а вы хотите получить название компании-работодателя:
var company = DbHelper.PeopleTable.Find(x => x.id == id).FirstOrDefault().EmploymentHistory.CompanyName;Если вы попытаетесь это сделать, возникнет ошибка. Как только в цепочке вызовов встречается
null
, всё пропало. В C#6 появился способ обойти это, используя оператор безопасной навигации после значений или полей, которые могут быть null
. Вот так:var company = DbHelper?.PeopleTable?.Find(x => x.id == id)?.FirstOrDefault()?.EmploymentHistory?.CompanyName;
Этот код будет переходить к следующему элементу в цепочке, только если предыдущий не
null
. В противном случае вся цепочка вернёт null
вместо выброса исключения. Это может быть удобно оставить проверки фреймворку, однако, несмотря на это, вам нужно будет проверить итоговый результат на null
.if(company != null) {Примечание! Стоит отметить, что при всём удобстве этого оператора есть соблазн спрятать плохое проектирование с его помощью, как в последнем примере. Всё-таки несмотря на то, что код не будет выдавать ошибок, связанных с неинициализированными объектами, он может скрыть ошибки, которые вы хотели бы обнаружить и исправить (например, неинициализированный объект DbHelper).
// Дальнейшая обработка
}
Источник: https://www.pluralsight.com/guides/tips-for-writing-better-c-code