18

MS アナライザーは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 アナライザーでは、パフォーマンス上の理由から、null または空の文字列と比較する代わりに、string.IsNullOrEmpty を使用することをお勧めします。

警告 470 CA1820 : Microsoft.Performance : ... の 'string.operator ==(string, string)' への呼び出しを 'String.IsNullOrEmpty' への呼び出しに置き換えてください。

細かいマニュアルを読むだけです:

Object.Equals を使用して、文字列を空の文字列と比較します。

...

String.Length プロパティまたは String.IsNullOrEmpty メソッドを使用して文字列を比較すると、Equals を使用するよりもはるかに高速です。これは、Equals が IsNullOrEmpty または Length プロパティ値を取得してゼロと比較するために実行された命令の数よりもはるかに多くの MSIL 命令を実行するためです。

...

この規則違反を修正するには、Length プロパティを使用するように比較を変更し、null 文字列をテストします。.NET Framework 2.0 を対象とする場合は、IsNullOrEmpty メソッドを使用します。

あなたの問題はそれほどチェックではありませんが、その代わりに、空のインスタンスをチェックするのではなく、 null(経由で)等しいかどうかをテストします。EqualsstringLength

繰り返しますが、細かいマニュアルから:

  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 に答える