web-dev-qa-db-ja.com

C#で「変数!= null」ではなく「null!=変数」と表示されることが多いのはなぜですか?

C#では、条件を述べる順序の実行速度に違いはありますか?

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

最近、最初のものを非常に頻繁に見ましたが、2番目のものに慣れていたのでそれが私の注意を引きました。

違いがない場合、最初の利点は何ですか?

98
mr_georg

これはCからの持ち越しです。Cでは、不正なコンパイラを使用するか、警告を十分に高くしないと、警告なしでコンパイルされます(実際に正当なコードです)。

// Probably wrong
if (x = 5)

あなたが実際におそらく意味したとき

if (x == 5)

Cでこれを回避するには、次のようにします。

if (5 == x)

ここにタイプミスがあると、無効なコードになります。

さて、C#ではこれはすべて厄介です。 2つのブール値(まれですが、IME)を比較する場合を除き、「if」ステートメントにはブール式と「x=5 "はInt32Booleanではありません。

同僚のコードでこれを見たら、現代の言語の方法でそれらを教育し、将来、より自然な形で書くことを提案することをお勧めします。

155
Jon Skeet

最初に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
    }
}
_
12
DanW

すでに述べたように、2番目の等号を誤って忘れた場合に誤ったコードを取得する可能性のあるC言語から来ていることは多かれ少なかれです。しかし、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 ...

次に何が来るかすぐにわかります。

逆の場合は、常にscanで行の終わりに移動して無効チェックを確認する必要があります。 。したがって、構文の強調表示が役立つ場合がありますが、それらのキーワードが行頭ではなく行末にある場合は常に遅くなります。

9
Oliver

これは言語を切り替えたCプログラマーだと思います。

Cでは、次のように記述できます。

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

単一の等号の使用に注意してください。つまり、コードは変数iに1を割り当て、1を返し(割り当ては式です)、ifステートメントで1を使用します。これはtrueとして処理されます。言い換えれば、上記はバグです。

ただし、C#ではこれは不可能です。実際、この2つの間に違いはありません。

この規則に従うことには何の利点もありません。ブール型が存在しないCでは、次のように書くと便利です。

if( 5 == variable)

のではなく

if (variable == 5)

等号のいずれかを忘れると、

if (variable = 5)

5を変数に割り当て、常にtrueと評価されます。しかし、Javaでは、ブールはブールです。 !!を使用すると、理由はまったくありません。

ただし、1つの良いアドバイスは、

if (CONSTANT.equals(myString))

のではなく

if (myString.equals(CONSTANT))

nullPointerExceptionsの回避に役立つためです。

私のアドバイスは、ルールの正当化を求めることです。ない場合は、なぜそれに従うのですか?読みやすさには役立ちません

4
Gokkula Sudan R

以前は、人々は「!」を忘れていました。 (または平等のための余分な「=」。これは見つけるのがより困難です)、比較の代わりに割り当てを行います。 nullを先頭に置くと、nullはl値ではないため(つまり、割り当てることができないため)、バグの可能性がなくなります。

最近のほとんどのコンパイラは、最近条件付きで割り当てを行うと警告を出し、C#は実際にエラーを出します。一部の人にとって読みやすいため、ほとんどの人はvar == nullスキームに固執しています。

4
Rik

私にとっては、常にどのスタイルを好むのか

@Shy-オペレーターを混乱させる場合は、コンパイルエラーを取得するか、バグでコードを実行します

0
TheCodeJunkie