120

次のことを行うためのより良い方法はありますか:
ループを続行する前に、file.Headers で null をチェックする必要があります 。

if (file.Headers != null)
{
  foreach (var h in file.Headers)
  {
   //set lots of properties & some other stuff
  }
}

要するに、コードでインデントのレベルが発生しているため、if 内に foreach を記述するのは少し見苦しく見えます。

に評価されるものです

foreach(var h in (file.Headers != null))
{
  //do stuff
}

可能?

4

7 に答える 7

152

Rune の提案へのちょっとした装飾的な追加として、独自の拡張メソッドを作成できます。

public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
    return source ?? Enumerable.Empty<T>();
}

次に、次のように記述できます。

foreach (var header in file.Headers.OrEmptyIfNull())
{
}

好みに応じて名前を変更してください:)

于 2012-07-31T06:40:41.253 に答える
92

file.Headers の要素のタイプが T であると仮定すると、これを行うことができます

foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
  //do stuff
}

file.Headers が null の場合、これは T の空の列挙型を作成します。ただし、ファイルのタイプが所有しているタイプである場合は、Headers代わりにゲッターを変更することを検討してください。nullは不明の値であるため、可能であれば、「要素がないことはわかっている」として null を使用する代わりに、実際に (/元々) null を「要素があるかどうかわからない」と解釈する必要がある場合は、空のセットを使用して表示しますセットに要素がないことがわかっていること。nullチェックを頻繁に行う必要がないため、これはDRY'erでもあります。

Jonsの提案のフォローアップとしてEDIT 、上記のコードを次のように変更する拡張メソッドを作成することもできます

foreach(var header in file.Headers.OrEmptyIfNull()){
  //do stuff
}

ゲッターを変更できない場合は、操作に名前 (OrEmptyIfNull) を付けることで意図がより明確に表現されるため、これが私の好みです。

上記の拡張メソッドにより、特定の最適化がオプティマイザで検出できなくなる場合があります。具体的には、これをオーバーロードするメソッドを使用して IList に関連するものを削除できます

public static IList<T> OrEmptyIfNull<T>(this IList<T> source)
{
    return source ?? Array.Empty<T>();
}
于 2012-07-31T06:37:43.337 に答える
24

null率直に言って、私はアドバイスします:ただテストを吸うだけです。nullテストは単なるaまたは;brfalseですbrfalse.s。他のすべてには、はるかに多くの作業が含まれます(テスト、割り当て、追加のメソッド呼び出し、不要なGetEnumerator()、、MoveNext()イテレータDispose()など)。

ifテストは単純で、明白で、効率的です。

于 2012-07-31T06:46:54.510 に答える
17

繰り返しの前の「if」は問題ありませんが、これらの「きれいな」セマンティクスのいくつかは、コードを読みにくくする可能性があります。

とにかく、インデントが邪魔になる場合は、if を変更して確認できます。

if(file.Headers == null)  
   return;

headers プロパティに true 値がある場合にのみ、foreach ループに到達します。

私が考えることができる別のオプションは、foreach ループ内で null 合体演算子を使用し、null チェックを完全に回避することです。サンプル:

List<int> collection = new List<int>();
collection = null;
foreach (var i in collection ?? Enumerable.Empty<int>())
{
    //your code here
}

(コレクションを実際のオブジェクト/タイプに置き換えます)

于 2012-07-31T06:39:35.583 に答える
3

これらのシナリオでは、ちょっとした拡張メソッドを使用しています。

  public static class Extensions
  {
    public static IList<T> EnsureNotNull<T>(this IList<T> list)
    {
      return list ?? new List<T>();
    }
  }

Headers がリスト型の場合、次のことができます。

foreach(var h in (file.Headers.EnsureNotNull()))
{
  //do stuff
}
于 2012-07-31T06:40:41.577 に答える