为什么在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#会实例化所有的变量,所以你不应该用那种语言来解决这个问题。