Почему в C # часто видят «null! = Variable» вместо «variable! = Null»? - PullRequest
97 голосов
/ 07 ноября 2008

В c #, есть ли разница в скорости исключения для заказа, в котором вы указали условие?

if (null != variable) ...
if (variable != null) ...

С недавнего времени я видел первый довольно часто, и он привлек мое внимание, так как я привык ко второму.

Если нет разницы, в чем преимущество первого?

Ответы [ 8 ]

153 голосов
/ 07 ноября 2008

Это удержание от C. В C, если вы используете плохой компилятор или у вас недостаточно высокие предупреждения, это скомпилируется без предупреждения (и действительно является допустимым кодом):

// Probably wrong
if (x = 5)

когда вы, вероятно, имели в виду

if (x == 5)

Вы можете обойти это в C, выполнив:

if (5 == x)

Опечатка приведет к неверному коду.

Теперь, в C # это все просто. Если вы не сравниваете два логических значения (что редко встречается, IME), вы можете написать более читаемый код, так как для оператора «if» требуется логическое выражение для начала, а тип «x=5» равен Int32 не Boolean.

Я полагаю, что если вы увидите это в коде ваших коллег, вы научите их современным языкам и предложите им написать более естественную форму в будущем.

12 голосов
/ 24 мая 2012

Есть веская причина, чтобы сначала использовать null: if(null == myDuck)

Если ваш class Duck переопределяет оператор ==, то if(myDuck == null) может войти в бесконечный цикл.

Использование null сначала использует компаратор равенства по умолчанию и фактически выполняет то, что вы намеревались.

(Я слышал, что в конце концов вы привыкли читать код, написанный таким образом - я просто еще не испытывал этого преобразования).

Вот пример:

public class myDuck
{
    public int quacks;
    static override bool operator ==(myDuck a, myDuck b)
    {
        // these will overflow the stack - because the a==null reenters this function from the top again
        if (a == null && b == null)
            return true;
        if (a == null || b == null)
            return false;

        // these wont loop
        if (null == a && null == b)
            return true;
        if (null == a || null == b)
            return false;
        return a.quacks == b.quacks; // this goes to the integer comparison
    }
}
9 голосов
/ 07 ноября 2008

Полагаю, это программист на Си, который переключил языки.

В C вы можете написать следующее:

int i = 0;
if (i = 1)
{
    ...
}

Обратите внимание на использование единственного знака равенства, что означает, что код назначит 1 переменной i, затем вернет 1 (присваивание является выражением) и использует 1 в операторе if, который будет обрабатываться как правда. Другими словами, вышесказанное является ошибкой.

Однако в C # это невозможно. Разницы между ними действительно нет.

8 голосов
/ 31 января 2013

Как все уже отметили, это происходит в большей или меньшей степени от языка Си, где вы можете получить ложный код, если случайно забудете второй знак равенства. Но есть и другая причина, которая также соответствует C #: удобочитаемость.

Просто возьмите этот простой пример:

if(someVariableThatShouldBeChecked != null
   && anotherOne != null
   && justAnotherCheckThatIsNeededForTestingNullity != null
   && allTheseChecksAreReallyBoring != null
   && thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded != null)
{
    // ToDo: Everything is checked, do something...
}

Если вы просто поменяете местами все слова null в начале, вы можете намного легче найти все проверки:

if(null != someVariableThatShouldBeChecked
   && null != anotherOne
   && null != justAnotherCheckThatIsNeededForTestingNullity
   && null != allTheseChecksAreReallyBoring
   && null != thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded)
{
    // ToDo: Everything is checked, do something...
}

Так что этот пример может быть плохим примером (обратитесь к руководству по кодированию), но просто подумайте о том, как быстро пролистать полный файл кода. Просто увидев рисунок

if(null ...

Вы сразу знаете, что будет дальше.

Если бы все было наоборот, вам всегда нужно отсканировать до конца строки, чтобы увидеть проверку недействительности, просто позволяя вам споткнуться на секунду, чтобы выяснить, что это за проверка оттуда Поэтому, возможно, подсветка синтаксиса может вам помочь, но вы всегда медленнее, когда эти ключевые слова находятся в конце строки, а не в начале.

4 голосов
/ 03 октября 2014

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

if( 5 == variable)

вместо

if (variable == 5)

потому что, если вы забудете один из знаков равенства, вы получите

if (variable = 5)

, который присваивает 5 переменной и всегда принимает значение true. Но в Java логическое значение является логическим. А с! = Нет вообще никакой причины.

Один хороший совет, однако, это написать

if (CONSTANT.equals(myString))

вместо

if (myString.equals(CONSTANT))

потому что это помогает избежать исключений NullPointerExceptions.

Мой совет - спросить об обосновании правила. Если их нет, зачем им следовать? Это не помогает читаемости

4 голосов
/ 07 ноября 2008

Раньше люди забывали «!» (или дополнительное '=' для равенства, которое труднее обнаружить) и сделайте присваивание вместо сравнения. помещение нулевого значения впереди исключает возможность ошибки, поскольку нулевое значение не является l-значением (т. е. ему нельзя присвоить).

Большинство современных компиляторов выдают предупреждение, когда вы делаете назначение в условном выражении в настоящее время, а C # фактически выдает ошибку. Большинство людей просто придерживаются схемы var == null, поскольку некоторым легче читать.

0 голосов
/ 09 июня 2009

Еще одна вещь ... Если вы сравниваете переменную с константой (целое число или строка, например, например), размещение константы слева является хорошей практикой, поскольку вы никогда не столкнетесь с NullPointerExceptions:

int i;
if(i==1){        // Exception raised: i is not initialized. (C/C++)
  doThis();
}

тогда

int i;
if(1==i){        // OK, but the condition is not met.
  doThis();
}

Теперь, поскольку по умолчанию C # создает все переменные, у вас не должно быть этой проблемы на этом языке.

0 голосов
/ 07 ноября 2008

Мне всегда был стиль, который вы предпочитаете

@ Застенчивый - опять же, если вы перепутаете операторы, то вы должны захотеть получить ошибку компиляции, или вы будете запускать код с ошибкой - ошибкой, которая возвращается и кусает вас позже, так как это приводило к неожиданному поведению

...