在c#中,你说明这个条件的命令的执行速度有什么不同吗?
if (null != variable) ...
if (variable != null) ...
最近,我经常看到第一个,因为我习惯了第二个,所以引起了我的注意。
如果没有差异,第一个的优势是什么?
答案 0 :(得分:153)
这是来自C的保留。在C中,如果您使用了错误的编译器或者没有足够高的警告,这将编译时没有任何警告(并且确实是合法代码):
// Probably wrong
if (x = 5)
当你真的可能意味着
if (x == 5)
您可以通过以下方式在C中解决此问题:
if (5 == x)
此处输入错误将导致代码无效。
现在,在C#中,这一切都是piffle。除非你比较两个布尔值(很少见,IME),否则你可以编写更易读的代码,因为“if”语句需要一个布尔表达式来开始,而“x=5
”的类型是{ {1}},而不是Int32
。
我建议,如果你在同事的代码中看到这一点,你就会用现代语言教育他们,并建议他们将来写出更自然的形式。
答案 1 :(得分:12)
首先使用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
}
}
答案 2 :(得分:9)
我想这是一位已经转换语言的C程序员。
在C中,您可以编写以下内容:
int i = 0;
if (i = 1)
{
...
}
注意在那里使用单个等号,这意味着代码将1分配给变量i,然后返回1(赋值是表达式),并在if语句中使用1,它将被处理为真正。换句话说,以上是一个错误。
然而,在C#中,这是不可能的。两者之间确实没有区别。
答案 3 :(得分:8)
就像所有人已经注意到的那样,它或多或少来自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 ...
你马上知道接下来会发生什么。
如果是相反的方式,你总是必须扫描到行的末尾才能看到无效检查,只是让你绊倒了一秒钟,找出什么样的检查是在那里。因此,语法突出显示可能会对您有所帮助,但是当这些关键字位于行的末尾而不是前面时,您总是会变慢。
答案 4 :(得分:4)
在早些时候,人们会忘记'!' (或更多的'='表示相等,更难以发现)并进行分配而不是比较。将null置于前面可以消除bug的可能性,因为null不是l值(I.E.它不能分配给它)。
现在大多数现代编译器都会在条件中执行赋值时发出警告,而C#实际上会出错。大多数人只是坚持使用var == null方案,因为对某些人来说它更容易阅读。
答案 5 :(得分:4)
我没有看到遵循这一惯例的任何优势。在C中,布尔类型不存在,写入
很有用if( 5 == variable)
而不是
if (variable == 5)
因为如果你忘记了其中一个等号,你最终会得到
if (variable = 5)
将5赋值给变量并始终求值为true。但在Java中,布尔值是布尔值。有了!=,根本就没有理由。
但是,一个好的建议就是写
if (CONSTANT.equals(myString))
而不是
if (myString.equals(CONSTANT))
因为它有助于避免NullPointerExceptions。
我的建议是要求对该规则进行辩护。如果没有,为什么要遵循它?它没有帮助可读性
答案 6 :(得分:0)
对我而言,你总是喜欢哪种风格
@Shy - 然后再次如果你混淆了操作符然后你应该想要得到一个编译错误,或者你将运行带有错误的代码 - 这个错误会在以后出现,并且会因为它产生意外行为而咬你/ p>
答案 7 :(得分:0)
正如许多人指出的那样,它主要是用旧的C代码来识别编译错误,因为编译器认为它是合法的
像java,go这样的新编程语言足够聪明,可以捕获此类编译错误
一个人不应该像代码中的条件那样使用“ null!= variable”,因为它非常不可读
答案 8 :(得分:-4)
还有一件事......如果你要将变量与常量(例如整数或字符串)进行比较,那么将常量放在左边是很好的做法,因为你永远不会遇到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#会对所有变量进行实例化,因此您不应该使用该语言存在该问题。