V3105. The 'a' variable was used after it was assigned through null-conditional operator. NullReferenceException is possible.
Данная диагностика предупреждает вас о возможном возникновении 'NullReferenceException' при выполнении программы. Предупреждение возникает в том случае, если происходит обращение к полю переменной без проверки её на 'null'. Ключевым моментом является то, что значение переменной вычисляется с помощью выражения, где используется оператор null-conditional.
Рассмотрим пример:
public int Foo (Person person)
{
string parentName = person?.Parent.ToString();
return parentName.Length;
}
В данном случае при инициализации объекта 'parentName' мы предполагаем, что 'person' может быть 'null'. В таком случае функция 'ToString()' не будет выполнена, а в переменную 'parentName' запишется 'null'. При попытке чтения свойства 'Length' из переменной 'parentName' возникнет исключение 'NullReferenceException'.
Исправленный код функции может быть следующим:
public int Foo (Person person)
{
string parentName = person?.Parent.ToString();
return parentName?.Length ?? 0;
}
Теперь, если в переменной 'parentName' не было 'null', то мы вернем длину строки, а если был 'null', то 0.
Ошибка может возникнуть, если значение, полученное с помощью null-conditional, без проверки передаётся в метод, конструктор или присваивается свойству.
Рассмотрим пример:
void UsersProcessing(Users users)
{
IEnumerable<User> usersList = users?.GetUsersCollection();
LogUserNames(usersList);
}
void LogUserNames(IEnumerable<User> usersList)
{
foreach (var user in usersList)
{
....
}
}
Переменная 'usersList' передаётся в качестве аргумента методу 'LogUserNames'. Она может иметь значение 'null', так как оно получено с помощью оператора null-conditional. Внутри 'LogUserNames' производится обход переданной коллекции. Для этого используется 'foreach' и, следовательно, у коллекции будет вызван метод 'GetEnumerator'. Если 'userList' имеет значение 'null', то будет выброшено исключение типа 'NullReferenceException'.
Вариант с исправлениями может выглядеть следующим образом:
void UsersProcessing(Users users)
{
IEnumerable<User> usersList = users?.GetUsersCollection();
LogUserNames(usersList ?? Enumerable.Empty<User>());
}
void LogUserNames(IEnumerable<User> usersList)
{
foreach (var user in usersList)
{
....
}
}
Результат выполнения 'users?.GetUsersCollection()' присваивается переменной 'usersList'. Если значение этой переменной — 'null', то в метод 'LogUserNames' будет передаваться пустая коллекция. Это поможет избежать исключения типа 'NullReferenceException' при обходе 'usersList' в 'foreach'.
Данная диагностика классифицируется как:
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3105. |