18

出于性能原因, MS Analyzer 建议使用string.IsNullOrEmpty它而不是与 null 或空字符串进行比较

警告 470 CA1820:Microsoft.Performance:将 ... 中对“string.operator ==(string, string)”的调用替换为对“String.IsNullOrEmpty”的调用。

这是为什么?调用另一个函数并将其传递给某个对象的要求不应该比执行比较本身更昂贵吗?

示例代码

void Foo()
{ // throws a warning
    string x = "hello world";
    if (x == null || x == "")
    {
        Console.WriteLine("Empty");
    }
}

void Foo()
{ // doesn't throw it
    string x = "hello world";
    if (string.IsNullOrEmpty(x))
    {
        Console.WriteLine("Empty");
    }
}
4

2 回答 2

19

出于性能原因,MS Analyzer 建议使用 string.IsNullOrEmpty 而不是将其与 null 或空字符串进行比较

警告 470 CA1820:Microsoft.Performance:将 ... 中对“string.operator ==(string, string)”的调用替换为对“String.IsNullOrEmpty”的调用。

只需阅读精美的手册

使用 Object.Equals 将字符串与空字符串进行比较。

...

使用 String.Length 属性或 String.IsNullOrEmpty 方法比较字符串比使用 Equals 快得多。这是因为 Equals 执行的 MSIL 指令明显多于 IsNullOrEmpty 或为检索 Length 属性值并将其与零进行比较而执行的指令数。

...

要修复违反此规则的情况,请将比较更改为使用 Length 属性并测试空字符串。如果面向 .NET Framework 2.0,请使用 IsNullOrEmpty 方法。

您的问题不是null检查,而是Equals使用空string实例测试相等性(通过)而不是检查其Length.

同样,来自精美的手册:

  public void EqualsTest()
  {
     // Violates rule: TestForEmptyStringsUsingStringLength. 
     if (s1 == "")
     {
        Console.WriteLine("s1 equals empty string.");
     }
  }

  // Use for .NET Framework 1.0 and 1.1. 
  public void LengthTest()
  {
     // Satisfies rule: TestForEmptyStringsUsingStringLength. 
     if (s1 != null && s1.Length == 0)
     {
        Console.WriteLine("s1.Length == 0.");
     }
  }
于 2013-08-29T10:07:26.560 回答
2

IsNullOrEmpty将被内联,因此将避免调用该方法的开销。看方法,是用属性修饰的

[__DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]

我还要补充一点,IsNullOrEmpty从可读性的角度来看(在我看来),它更清晰、更具描述性。

至于性能,如果您使用value.Length == 0;而不是x == "". 在内部,IsNullOrEmpty这样做

return value == null || value.Length == 0;

不是

if (x == null || x == "")

读取属性比计算相等性需要更少的开销。

于 2013-08-29T09:56:39.047 回答