应该在左侧或右侧检查null

Dav*_*ter 6 c# null coding-style

在回顾一些代码时,我看到:

if (null == condition) { ... }
Run Code Online (Sandbox Code Playgroud)

我也看到了:

if (condition == null) { ... }
Run Code Online (Sandbox Code Playgroud)

我似乎记得null在左侧有一个优势,但是我记不住它了,并且认为它是一个较旧的运行时项目,它已经被更新的.NET运行时优化了.我倾向于使用后者的无效检查,所以前者引起了我的注意.

那么这是一种风格问题,还是null在评估的左侧或右侧有优势?

Dav*_*veR 7

C风格语言的经典原因是防止错误输入==作为赋值的相等性=.你不能分配一个常量 - 即以下是非法的,因此编译器将捕获该错误:

if (false = condition) { ... }
Run Code Online (Sandbox Code Playgroud)

虽然这是完全合法的(但可能不是作者的意图:

if (condition = false) { ... }
Run Code Online (Sandbox Code Playgroud)

注意:这个问题在C#中有限(与vanilla C相比),因为if语句需要bool(如下面的注释中所述),所以这实际上导致问题的唯一情况是你的类型是a bool.


Jon*_*nna 6

它可以在三种情况下产生影响。

一种是 的拼写错误condition = nullif. 这在 C 风格的语言中更常见,它允许null使用if(值为false),这是大多数语言,但不是 C#。

可以在 C# 中创建具有这种效果的类型:

public class Test
{
  public static bool operator true(Test x)
  {
    return true;
  }
  public static bool operator false(Test x)
  {
    return false;
  }
}
void Main()
{
  Test test = new test();
  if (test = null)
  {
    Console.WriteLine("!");
  }
}
Run Code Online (Sandbox Code Playgroud)

很多时候重载这些运算符是没有意义的,特别是因为 .Net 2.0 引入了泛型(它对于像SqlBoolean这样的类型具有更多的价值,使值能够指示truefalse或者null我们现在使用的方式bool?)。

所以这种情况在 C# 中是非常边缘的。

另一个是类似的,如果有一个隐式转换到bool或到一个类型,又实现了trueandfalse运算符:

void Main()
{
  Test test = new Test();
  if (test = null)
  {
    Console.WriteLine("!");
  }
}
public class Test
{
  public static implicit operator bool(Test x)
  {
    return true;
  }
}
Run Code Online (Sandbox Code Playgroud)

由于一些原因,隐式运算符值得避免,但这比第一个示例的可能性稍大,尽管仍然远不及常见。

另一个是 if==以非对称方式重载:

public class Test
{
  public static bool operator == (Test x, Test y)
  {
    return ReferenceEquals(x, null);
  }
  public static bool operator !=(Test x, Test y)
  {
    return !(x == y);
  }
}
void Main()
{
  Test test = new Test();
  if (test == null)
  {
    Console.WriteLine("This won't print.");
  }
  if (null == test)
  {
    Console.WriteLine("This will print.");
  }
}
Run Code Online (Sandbox Code Playgroud)

但是由于非对称==总是一个错误,那么这取决于运算符中的错误是否会产生任何影响。这可能比第一种情况更频繁地发生,但它应该在它发生时修复,所以它更不用担心。

因此,虽然它可以在 C# 中产生影响,但这种情况很少见,而且主要是基于其他人做了他们不应该做的事情。

因此,它主要是风格问题。把它null放在第一位的人往往是从它产生更大差异的语言中学到的。