Анализатор обнаружил фрагмент кода, который, скорее всего, содержит логическую ошибку. В тексте программы имеется выражение, содержащее оператор '??' или '?:', которое может вычисляться не так, как планировал программист.
Операторы '??' и '?:' имеют более низкий приоритет по сравнению с операторами ||, &&, |, ^, &, !=, ==, +, -, %, /, *. Это можно случайно забыть и написать ошибочный код, подобный приведенному ниже:
public bool Equals(Edit<TNode> other)
{
return _kind == other._kind
&& (_node == null) ? other._node == null :
node.Equals(other._node);
}
Так как приоритет оператора '&&' выше чем оператора '?:', то сначала будет выполнено выражение '_kind == other._kind && (_node == null)'. Чтобы избежать таких ошибок, следует заключать всё выражение, содержащее оператор '?:', в скобки:
public bool Equals(Edit<TNode> other)
{
return _kind == other._kind
&& ((_node == null) ? other._node == null :
node.Equals(other._node));
}
Рассмотрим другой пример с оператором '??':
public override int GetHashCode()
{
return ValueTypes.Aggregate(...)
^ IndexMap?.Aggregate(...) ?? 0;
}
Приоритет оператора '^' выше чем приоритет оператора '??', поэтому если 'IndexMap' равен 'null', то и левая часть оператора '??' тоже будет иметь значение 'null', и значит функция всегда будет возвращать 0 вне зависимости от того что содержится в коллекции 'ValueTypes'.
Как и в случае оператора '?:', выражение с оператором '??' лучше заключать в скобки
public override int GetHashCode()
{
return ValueTypes.Aggregate(...)
^ (IndexMap?.Aggregate(...) ?? 0);
}
Теперь функция 'GetHashCode()' будет возвращать разные значения в зависимости от содержимого коллекции 'ValueTypes' и в том случае когда 'IndexMap' будет равен 'null'.
Данная диагностика классифицируется как:
Взгляните на примеры ошибок, обнаруженных с помощью диагностики V3123. |