# V3207. The 'not A or B' logical pattern may not work as expected. The 'not' pattern is matched only to the first expression from the 'or' pattern.

Анализатор обнаружил фрагмент кода, который, возможно, содержит логическую ошибку. В условном выражении был обнаружен паттерн 'is not * or *'. Приоритет оператора 'not' выше, чем у оператора 'or'. Вследствие этого отрицание не применяется к правой части 'or'.

Рассмотрим пример:

    private void ShowWordDetails(string key)
    {
      if (key is not "" or null)
      {
        PanelReferenceBox.Controls.Clear();

        CurrentWord = Words.Find(x => x.Name == key);
        ....
      }
    }

Логика выражения 'key is not "" or null' нарушена. Если 'key' – null, то результатом логического выражения будет 'true', когда подразумевался 'false'.

Ошибка возникает, если разработчик не учитывает, что оператор 'not' имеет приоритет выше, чем 'or'. В данном паттерне второе подвыражение оператора 'or', как правило, оказывается бессмысленным. Например, в выражении 'key is not "" or null', если 'key' – null, при проверке на не пустую строку будет получен результат 'true'. Получается, что вторая часть выражения не будет влиять на конечный результат.

Для корректного порядка выполнения операторов стоит использовать скобки после оператора 'not'.

Исправленный код:

    private void ShowWordDetails(string key)
    {
      if (key is not ("" or null))
      {
        PanelReferenceBox.Controls.Clear();

        CurrentWord = Words.Find(x => x.Name == key);
        ....
      }
    }

Теперь код работает, как ожидалось. В условии проверяется, что строка 'key' не пустая и не 'null', вместо проверки только на пустую строку.

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

CWE-670

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