>
>
>
V3156. The argument of the method is no…


V3156. The argument of the method is not expected to be null.

Анализатор обнаружил возможную ошибку, связанную с тем, что в метод в качестве аргумента, не ожидающего 'null', может передаваться значение 'null'.

Это может привести, например, к возникновению исключения или неправильному исполнению вызываемого метода.

При написании кода бывает сложно отследить, были ли добавлены проверки на 'null' во всех необходимых местах. Это особенно актуально, когда переменная, которая может иметь значение 'null', передается в метод, внутри которого используется как аргумент другого метода, не ожидающего значение 'null'.

Рассмотрим небольшой синтетический пример:

void Method(string[] args)
{
  var format = args.Length != 0 ? args[0] : null;
  ....
  var message = string.Format(format, _value);
  // do something
}

Если массив 'args' не содержит элементов, в переменную 'format' будет записано значение 'null'. Следовательно, в метод 'string.Format' в качестве первого аргумента будет передано значение 'null', что приведет к возникновению исключения. Исправить это можно следующим образом:

void Method(string[] args)
{
  var format = args.Length != 0 ? args[0] : null;
  ....
  if (format == null)
  {
    // process an error
    return;
  }

  var message = string.Format(format, _value);
  // do something
}

Немного усложним пример выше:

void Method(string[] args)
{
  var format = args.Length != 0 ? args[0] : null;
  ....
  WriteInfo(format);
}

void WriteInfo(string format)
{
  Console.Write(format, _value);
}

Переменная 'format' все так же зависит от 'args.Length' и потенциально может быть 'null'. В данном случае считаем, что 'format == null'. Соответственно, в метод 'WriteInfo' также будет передано значение 'null'. Далее это же значение будет передано в качестве первого аргумента в метод 'Console.WriteLine', что приведёт к возникновению исключения типа 'ArgumentNullException'.

Исправим это аналогичным образом:

void Method(string[] args)
{
  var format = args.Length != 0 ? args[0] : null;
  ....
  WriteInfo(format);
}

void WriteInfo(string format)
{
  if (format == null)
  {  
    // process an error
    return;
  }
  Console.Write(format, _value);
}

Теперь рассмотрим реальный пример:

private static string HandleSuffixValue(object val, StringSegment suffixSegment)
{
  ....
  var res = string.Format(suffixSegment.Value, val).TrimEnd(']');
  return res == "" ? null : res;
}

Первый аргумент метода 'string.Format' не должен быть равен 'null'. Давайте посмотрим, что возвращает 'suffixSegment.Value':

public string Value
{
  get
  {
    if (HasValue)
    {
      return Buffer.Substring(Offset, Length);
    }
    else
    {
      return null;
    }
  }
}

Если 'HasValue' будет 'false', то 'Value' вернет 'null'. Получается, что потенциально вызов метода 'string.Format' в данном случае может выбросить исключение. Пример исправленного варианта:

private static string HandleSuffixValue(object val, StringSegment suffixSegment)
{
  ....
  if (suffixSegment.Value == null)
  {
    return null;
  }

  var res = string.Format(suffixSegment.Value, val).TrimEnd(']');
  return res == "" ? null : res;
}

Данная диагностика классифицируется как:

Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3156.