在c#中,陈述条件的顺序的执行速度是否有差异?
if (null != variable) ...
if (variable != null) ...
从最近开始,我经常看到第一个,自从我习惯了第二个以来,它引起了我的注意。
如果没有区别,第一个的优势是什么?
在c#中,陈述条件的顺序的执行速度是否有差异?
if (null != variable) ...
if (variable != null) ...
从最近开始,我经常看到第一个,自从我习惯了第二个以来,它引起了我的注意。
如果没有区别,第一个的优势是什么?
Answers:
这是C语言的保留。在C语言中,如果您使用的是错误的编译器或没有将警告调得足够高,那么它将在没有警告的情况下进行编译(实际上是合法代码):
// Probably wrong
if (x = 5)
当你实际上可能意味着
if (x == 5)
您可以通过以下方法在C中解决此问题:
if (5 == x)
此处输入错误将导致代码无效。
现在,在C#中,这真是个难题。除非您要比较两个布尔值(IME很少见),否则您可以编写更具可读性的代码,因为“ if”语句要求以布尔值开头,而“ x=5
” 的类型为Int32
,不是Boolean
。
我建议,如果您在同事的代码中看到了这一点,请以现代语言的方式对其进行教育,并建议他们将来编写更自然的形式。
else { }
子句,以防以后有人需要在其中添加一些内容而忘记自己编写else
关键字。(笑话)
有充分的理由先使用null: if(null == myDuck)
如果您class Duck
覆盖==
运算符,则if(myDuck == null)
可能会陷入无限循环。
使用null
first将使用默认的相等比较器,并实际执行您想要的操作。
(我听说您最终习惯了以这种方式编写的代码的阅读-我只是还没有经历过这种转换)。
这是一个例子:
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)
。
就像每个人都已经指出的那样,它或多或少地来自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语言中,编写
if( 5 == variable)
而不是
if (variable == 5)
因为如果忘记其中一个等号,您最终会得到
if (variable = 5)
将5赋给变量,并始终求值为true。但是在Java中,布尔值是布尔值。并且使用!=根本没有任何理由。
不过,一个好的建议是写
if (CONSTANT.equals(myString))
而不是
if (myString.equals(CONSTANT))
因为它有助于避免NullPointerExceptions。
我的建议是要求对规则进行辩护。如果没有,为什么要遵循?它不利于可读性
对我来说,一直是您喜欢哪种风格
@Shy-再一次,如果您使操作员感到困惑,那么您应该会遇到编译错误,否则您将在运行代码时遇到一个错误-一个错误会再次出现并在以后咬住您,因为它产生了意外的行为
正如许多人指出的那样,它主要是在旧的C代码中用于识别编译错误,因为编译器认为它是合法的
像Java这样的新编程语言go足够聪明,可以捕获此类编译错误
人们不应该像代码中的条件那样使用“ null!= variable”,因为它非常不可读
还有一件事...如果将变量与常量(例如整数或字符串)进行比较,则将常量放在左侧是一种好习惯,因为您永远不会遇到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#会实例化所有变量,因此您不应该在该语言中遇到该问题。
i
是未经适当初始化的随机值。该表达式在c / c ++中具有完全相同的语义