为什么null == myVar而不是myVar == null?

时间:2009-09-20 23:29:41

标签: c# .net vb.net

  

可能重复:
  Why does one often see “null != variable” instead of “variable != null” in C#?

我时不时地看到它,我想知道为什么。是否有任何区别?

6 个答案:

答案 0 :(得分:20)

避免myVar = null(哎呀)的意外拼写是一种老习惯。它在某些语言中仍然有用,但C#会保护你不会这样做,因此没有必要。

答案 1 :(得分:8)

这是来自C的保留,旧的编译器不会抓住这个:

if (foo = null)

当你的意思是:

if (foo == null)

经典笑话的例子就是这个错误:

if (fireTheNukes = true)
    fireTheNukes();

这通常被认为是一种古老的模式,因为任何有价值的编译器都会在条件语句中捕获赋值。我会在你的代码中避免使用这种模式,因为它现在没有任何用处。

答案 2 :(得分:2)

这是一种古老的防御习惯。如果将常量放在左侧,则忘记第二个等号将导致编译错误。在更正常的格式中,忘记第二个等号将导致为变量赋值null。

换句话说,

myVar = null

是有害且令人惊讶的,而

null = myVar

被编译器捕获。

答案 3 :(得分:2)

这是C程序员的习惯,在这种情况下已经被带到C#,但事实上完全没必要。

在C中考虑如果你不小心输入if (myVar = null),编译器将执行赋值而不是抱怨。切换myVarnull的顺序可确保在==无意中错误输入=时生成编译器错误。但是,C#在任何一种情况下都会生成编译器警告,因此这个怪癖是不必要的。

答案 4 :(得分:2)

它来自C / C ++,可以忽略一个等号:

myVar = null

但是在C#中不需要它。

答案 5 :(得分:1)

正如其他人所提到的那样,这是一种针对问题的防御策略,可能是由于在C和某些C衍生物(包括C#)中,赋值表达式评估该赋值的值。这是允许你这样做的:

if (a = true) { /* This will always get done, as "a = true" evals to true */ }

int a = b = c = d = 10;

由于赋值是正确的关联,这实际上是

int a = (b = (c = (d = 10)));

其中括号对内的每个表达式将计算为赋值的值,在这种情况下为10,a,b,c和d因此都为10。

为了避免潜在的错误 - 混合赋值和相等运算符 - 一些程序员喜欢总是将常量放在左边,就好像赋值运算符被意外使用一样,编译器会抱怨你不能赋值给常量。

然而,由于两个原因,这在C#中不是问题。首先,与C不同,C#不允许将任意值解释为布尔值。

这在C中是必要的,因为它没有真正的布尔类型,它只依赖于其他值的解释,如整数(其中0为假,非零为真)或指针(其中NULL为假)。这意味着您可以执行类似

的操作
if (10) { /* This will always get done */ }
if (0) { /* This will never get done */ }
if (p) { /* This will get done is p is not null */ }
if (NULL) { /* This will never get done */ }

但是,因为C#不允许将任意表达式解释为布尔值,所以它们在C#中不起作用。这也意味着

if (a = 10) { }

不会在C#中编译,因为表达式“a = 10”计算表达式10的值,然后不能将其解释为所需的布尔值。

它不是一个问题的第二个原因是,在现在小得多的情况下,分配结果可以被解释为布尔值,编译器发出警告以确保你真正意味着那样做。

可以使用

来抑制警告
#pragma warning disable 665

然而,这些代码的存在通常是一个糟糕的代码气味,最好通过重构来处理,以使代码更清晰。