为什么在C#中经常看到“null!= variable”而不是“variable!= null”呢?
在c#中,你声明条件的顺序在执行速度上有什么不同?
if (null != variable) ... if (variable != null) ...
自从最近,我经常看到第一个,因为我习惯了第二个,所以引起了我的注意。
如果没有区别,第一个的优点是什么?
这是C的保留。在C中,如果你使用了一个不好的编译器,或者没有足够高的警告,那么这个编译器就不会有任何警告(而且确实是合法的代码):
// Probably wrong if (x = 5)
当你实际上可能的意思
if (x == 5)
你可以用C来解决这个问题:
if (5 == x)
这里的错字将导致无效的代码。
现在,在C#中这是一切。 除非你比较两个布尔值(这是罕见的,IME),你可以编写更易读的代码,因为“if”语句需要一个布尔表达式来启动,而“ x=5
”的类型是Int32
,而不是Boolean
。
我建议,如果你在同事的代码中看到这个,你就用现代语言的方式来教育他们,并且建议他们将来写出更自然的形式。
首先使用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 } }
我想这是一个C语言程序员。
在C中,您可以编写以下内容:
int i = 0; if (i = 1) { ... }
注意在那里使用了一个等号,这意味着代码将赋值1给变量i,然后返回1(赋值是一个表达式),并且在if语句中使用1,将被处理为true。 换句话说,以上是一个错误。
但在C#中,这是不可能的。 两者确实没有区别。
就像大家已经注意到的那样,如果你不小心忘记了第二个等号的话,那么它就会和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 ...
你马上知道接下来会发生什么。
如果是反过来的话,你总是要扫描到行尾才能看到无效检查,只是让你绊倒一秒钟,找出在那里做什么样的检查。 所以,语法突出显示可能会对你有所帮助,但是当这些关键字位于行尾而不是前面时,你总是比较慢。
在早些时候,人们会忘记“!” (或多余的'='为平等,这是更难以发现),并做一个任务,而不是比较。 把null放在前面消除了bug的可能性,因为null不是l值(IE不能被赋值)。
大多数现代编译器在当今条件下进行赋值时会发出警告,而C#实际上会给出错误。 大多数人只是坚持var == null方案,因为它更容易阅读一些人。
遵循这个惯例我没有看到任何优势。 在C中,布尔类型不存在的情况下,写入是有用的
if( 5 == variable)
而不是
if (variable == 5)
因为如果你忘记了一个eaqual标志,你最终会结束
if (variable = 5)
它将5分配给变量,并总是评估为真。 但在Java中,布尔是一个布尔值。 而且!=,根本没有理由。
一个很好的建议是编写
if (CONSTANT.equals(myString))
而不是
if (myString.equals(CONSTANT))
因为它有助于避免NullPointerExceptions。
我的建议是要求对规则进行辩解。 如果没有,为什么要遵循它? 它不利于可读性
对我而言,你总是喜欢哪种风格
@Shy – 然后,如果你混淆了操作符,那么你应该想要得到一个编译错误,否则你将运行一个错误的代码 – 一个错误,它会在以后回来,
还有一件事情…如果你将一个变量与一个常量(整数或字符串)相比较,把常量放在左边是一个好习惯,因为你永远不会遇到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#会实例化所有的变量,所以你不应该用那种语言来解决这个问题。