以下を行うより良い方法があります:
file.Headersでnullをチェックしてからループに進む必要があります
if (file.Headers != null)
{
foreach (var h in file.Headers)
{
//set lots of properties & some other stuff
}
}
要するに、コード内で発生するインデントのレベルのために、if内にforeachを書くのは少しbitいように見えます。
評価されるものです
foreach(var h in (file.Headers != null))
{
//do stuff
}
可能?
ルーンの提案へのわずかな化粧品の追加と同様に、独自の拡張メソッドを作成できます。
public static IEnumerable<T> OrEmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}
その後、あなたは書くことができます:
foreach (var header in file.Headers.OrEmptyIfNull())
{
}
好みに応じて名前を変更してください:)
File.Headersの要素のタイプがTであると仮定すると、これを行うことができます
foreach(var header in file.Headers ?? Enumerable.Empty<T>()){
//do stuff
}
これは、file.Headersがnullの場合、Tの空の列挙型を作成します。ただし、ファイルのタイプが自分が所有するタイプである場合は、代わりにHeaders
のゲッターを変更することを検討してください。 null
はunknownの値なので、可能であれば、nullを実際に(/元々)nullを「要素が存在するかどうかわからない」と解釈する場合、nullを「要素がないことを知っている」として使用する代わりに空のセットを使用して、セットに要素がないことを示します。また、nullチェックを頻繁に行う必要がないので、これはより乾燥しています。
[〜#〜] edit [〜#〜] Jonsの提案のフォローアップとして、上記のコードを次のように変更する拡張メソッドを作成することもできます。
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>();
}
率直に言って、私はアドバイスします:null
テストを吸うだけです。 null
テストはjust a brfalse
または_brfalse.s
_;です。それ以外のすべての作業には、より多くの作業が必要になります(テスト、割り当て、追加のメソッド呼び出し、イテレーターでの不要なGetEnumerator()
、MoveNext()
、Dispose()
など)。
if
テストは単純で、明白で、効率的です。
反復の前の「if」は問題ありませんが、これらの「きれいな」セマンティクスのいくつかはコードを読みにくくします。
とにかく、インデントが邪魔な場合は、チェックするifを変更できます。
if(file.Headers == null)
return;
そして、headersプロパティにtrue値がある場合にのみforeachループに到達します。
私が考えることができるもう1つのオプションは、foreachループ内でnull結合演算子を使用し、nullチェックを完全に回避することです。サンプル:
List<int> collection = new List<int>();
collection = null;
foreach (var i in collection ?? Enumerable.Empty<int>())
{
//your code here
}
(コレクションを実際のオブジェクト/タイプに置き換えます)
Null-conditional Operator およびForEach()を使用すると、標準のforeachループよりも高速に動作します。
ただし、コレクションをリストにキャストする必要があります。
listOfItems?.ForEach(item => // ... );
私はこれらのシナリオにニースの小さな拡張メソッドを使用しています:
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
}
場合によっては、原則として、デフォルトのコレクションコンストラクターが空のインスタンスを返すと仮定して、少し別の汎用バリアントを好む場合があります。
このメソッドにNewIfDefault
という名前を付ける方が良いでしょう。コレクションだけでなく、型制約IEnumerable<T>
は冗長かもしれません。
public static TCollection EmptyIfDefault<TCollection, T>(this TCollection collection)
where TCollection: class, IEnumerable<T>, new()
{
return collection ?? new TCollection();
}