c#では、条件を述べる順序の実行速度に違いはありますか?
if (null != variable) ...
if (variable != null) ...
最近から最初の方をよく見ましたが、2番目に慣れてから気になりました。
違いがない場合、最初のものの利点は何ですか?
c#では、条件を述べる順序の実行速度に違いはありますか?
if (null != variable) ...
if (variable != null) ...
最近から最初の方をよく見ましたが、2番目に慣れてから気になりました。
違いがない場合、最初のものの利点は何ですか?
回答:
これはCからの持ち越しです。Cでは、不適切なコンパイラを使用するか、警告が十分に高くならない場合、警告なしでコンパイルされます(実際に正当なコードです)。
// Probably wrong
if (x = 5)
あなたが実際におそらく意味したとき
if (x == 5)
Cでこれを回避するには、次のようにします。
if (5 == x)
ここにタイプミスがあると、コードが無効になります。
さて、C#ではこれはすべて簡単です。あなたは(まれで、IME)2つのブール値を比較している場合を除き文がで開始するブール式を必要とする「場合」、および「の種類として、あなたは、より読みやすいコードを書くことができるx=5
」であるInt32
、ではありませんBoolean
。
同僚のコードでこれを目にした場合は、現代の言語の方法でそれらを教育し、将来、より自然な形式を書くことをお勧めします。
else { }
誰かが後で何かを追加する必要があり、else
自分でキーワードを書くのを忘れた場合に備えて、常に空の句を提供することを忘れないでください。(ジョーク)
最初に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
}
}
==
オペレーターの上にマウスを置くだけで、その上に置くと、両方のケースでユーザー定義のオーバーロードが使用されていることがわかります。もちろん、a
前に確認してから、右側のオペランドから左側のオペランドにb
位置を入れ替えると、微妙な違いが生じますa
。しかし、あなたはb
前a
にチェックすることもでき、それからb == null
順序を逆にしたものになります。これは、オペレーターが自分自身を呼び出すのを混乱させるものです。代わりに、いずれかのオペランド(または両方)をキャストobject
して、目的のオーバーロードを取得します。同様if ((object)a == null)
かif (a == (object)null)
。
すでに述べたように、それは多かれ少なかれ2番目の等号を忘れた場合に誤ったコードを取得する可能性があるC言語から来ています。しかし、C#にも一致する別の理由があります。それは、読みやすさです。
この単純な例を見てみましょう:
if(someVariableThatShouldBeChecked != null
&& anotherOne != null
&& justAnotherCheckThatIsNeededForTestingNullity != null
&& allTheseChecksAreReallyBoring != null
&& thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded != null)
{
// ToDo: Everything is checked, do something...
}
すべてのヌルワードを最初に置き換えるだけであれば、すべてのチェックを簡単に見つけることができます。
if(null != someVariableThatShouldBeChecked
&& null != anotherOne
&& null != justAnotherCheckThatIsNeededForTestingNullity
&& null != allTheseChecksAreReallyBoring
&& null != thereSeemsToBeADesignFlawIfSoManyChecksAreNeeded)
{
// ToDo: Everything is checked, do something...
}
したがって、この例はおそらく悪い例ですが(コーディングのガイドラインを参照)、コードファイル全体をすばやくスクロールすることを考えてください。パターンを見るだけで
if(null ...
次に何が起こるかすぐにわかります。
逆の場合は、常に行末までスキャンして無効性チェックを確認する必要があります。そこでつまずいて、そこで行われているチェックの種類を確認します。したがって、構文の強調表示が役立つ場合がありますが、これらのキーワードが先頭ではなく行末にある場合は常に遅くなります。
これは言語を切り替えたCプログラマだと思います。
Cでは、次のように記述できます。
int i = 0;
if (i = 1)
{
...
}
そこでは、単一の等号の使用に注意してください。これは、コードが変数iに1を割り当て、次に1(割り当ては式)を返し、ifステートメントで1を使用します。これはtrueとして処理されます。つまり、上記はバグです。
ただし、C#ではこれは不可能です。確かに両者には違いはありません。
以前は、人々は「!」を忘れていました。(または、等号の場合は追加の '='で、これを見つけるのはより困難です)、比較の代わりに割り当てを行います。nullを前に配置すると、nullはl値ではない(つまり、割り当てられない)ため、バグの可能性がなくなります。
最近のほとんどのコンパイラでは、条件付きで割り当てを行うと警告が表示され、C#では実際にエラーが発生します。一部の人にとっては読みやすいので、ほとんどの人はvar == nullスキームに固執します。
この慣習に従うことには何の利点もありません。ブール型が存在しないCでは、次のように書くと便利です。
if( 5 == variable)
のではなく
if (variable == 5)
等号のいずれかを忘れると、
if (variable = 5)
これは変数に5を割り当て、常にtrueと評価します。しかし、Javaでは、ブール値はブール値です。そして!=の場合、理由はまったくありません。
ただし、1つの良いアドバイスは、
if (CONSTANT.equals(myString))
のではなく
if (myString.equals(CONSTANT))
NullPointerExceptionsを回避するのに役立ちます。
私のアドバイスは、ルールの正当化を求めることです。ない場合は、なぜそれをフォローするのですか?それは読みやすさを助けません
私にとっては常にあなたが好むスタイルでした
@恥ずかしがり屋-次に、演算子を混乱させると、コンパイルエラーが発生するか、バグでコードを実行する必要があります-バグは戻ってきて、予期せぬ動作を引き起こしたため、後であなたを噛んでしまいます
もう1つ...変数を定数(ex。の場合は整数または文字列)と比較する場合は、定数を左側に置くことをお勧めします。
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#はすべての変数をインスタンス化するので、その言語ではそのような問題はないはずです。
i
。適切な初期化なしのランダムな値であるとしましょう。式の意味はc / c ++でもまったく同じです