>
>
>
V3168. Awaiting on expression with pote…


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.