V3168. Awaiting on expression with potential null value can lead to throwing of 'NullReferenceException'.
Анализатор обнаружил фрагмент, в котором оператор 'await' используется с выражением, значением которого может быть нулевая ссылка. При использовании 'await' с 'null' будет выброшено исключение типа 'NullReferenceException'.
Рассмотрим пример:
async void Broadcast(....)
{
await waiter.GetExplorerBehavior()?.SaveMatches();
....
}
ExplorerBehavior GetExplorerBehavior()
{
return _state == NodeState.HandShaked ? _Node.Behavior : null;
}
В методе 'Broadcast' оператор 'await' используется с выражением, которое в определённых случаях может иметь значение 'null'. Дело в том, что метод 'GetExplorerBehaviour' при некоторых обстоятельствах возвращает 'null', который впоследствии попадёт в 'Broadcast'.
В результате, при использовании оператора 'await' с выражением, имеющим значение 'null', будет выброшено исключение типа 'NullReferenceException'.
В качестве исправления можно добавить в метод 'Broadcast' дополнительную проверку на 'null':
async void Broadcast(....)
{
var task = waiter.GetExplorerBehavior()?.SaveMatches();
if (task != null)
await task;
....
}
Анализатор также предупреждает о случаях, когда потенциально нулевая ссылка передаётся в метод, конструктор или свойство, внутри которого она может быть использована с 'await'. Пример:
void ExecuteActionAsync(Action action)
{
Task task = null;
if (action != null)
task = new Task(action);
ExecuteTask(task); // <=
....
}
async void ExecuteTask(Task task)
{
....
await task;
}
В данном фрагменте 'await' используется с параметром 'task', в который при вызове передаётся потенциально нулевая ссылка. Ниже представлен исправленный вариант метода 'ExecuteActionAsync':
void ExecuteActionAsync(Action action)
{
Task task = null;
if (action != null)
{
task = new Task(action);
ExecuteTask(task);
}
....
}
Данная диагностика классифицируется как:
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3168. |