2011-12-19 3 views
58

C#ではLINQとIEnumerableを使います。そして、すべては善良で良い(または少なくともほとんどそうである)。C#に「空リスト」シングルトンがありますか?

しかし、ほとんどの場合、私は空のIEnumerable<X>をデフォルトとして必要としています。つまり、ヌルチェックを必要とせずに

for (var x in xs) { ... } 

を動作させていただきたいと思います。アレイを作成して任意の「余分なオーバーヘッド」がある場合、である - 上記の私ためまったく問題ありながら、今

var xs = f() ?? new X[0];    // when xs is assigned, sometimes 
for (var x in xs ?? new X[0]) { ... } // inline, sometimes 

:今、これは私が現在より大きな文脈に応じて、何をすべきかです私はちょうどを気にしないオブジェクト - 私は思っていた:C#の/の "空の不変のIEnumerable/IListの" シングルトンは、NET

ありますか。?(そして、してもいない場合は、上記のケースを処理するために、「より良い」方法はありますか?)

JavaはCollections.EMPTY_LIST不変シングルトンがある - Collections.emptyList<T>()を経由して「よく型付け」 - 私が、この目的を果たしますジェネリックスが異なる方法で処理されるため、C#でも同様の概念が機能するかどうかはわかりません。

ありがとうございました。

+0

まあ、これは私がList/IListに焦点を当て、Enumerable/IEnumerableではなく、全員に感謝しています。 –

+0

http:// stackoverflow。COM /質問/ 3229698 /方法缶-I-戻り、空のIEnumerable –

+1

'パブリック静的クラスArray {パブリック静的読み取り専用T []は空=新しいT [0]。 } 'と呼び、それは' Array .Empty'のように呼び出すことができます。私は[ここCodeReview](http://codereview.stackexchange.com/q/20417/17039)について尋ねました。 –

答えて

68

は吸います。

+0

それは非常に有効なポイントです!おそらくそれは新しいSOの質問を保証するでしょうか? –

+1

あなたは数秒遅く、ドキュメンテーションのリンクもありませんでした。しかし、svicksのコメントを拡大して受け入れます。私たちも:) しているので、 –

+0

はまた、他の人がより多くのupvotesを得た私は、質問を投稿するだろうが、今はベッドに行くんだと私は質問をたどることができません。なぜ自分で投稿するのですか? – Stilgar

17

私はあなたがEnumerable.Empty<T>()を探していると思います。

リストが頻繁に変更可能であるため、空リストのシングルトンはあまり意味がありません。 Listインタフェースは、例外をスローし、リストに要素を追加するためのメソッドを公開するので、あなたはJavaの空のリスト他のニュースではEnumerable.Empty<int>();

を探している

10

私は、拡張メソッドを追加すると、NULL値を処理する能力にクリーンな代替のおかげだと思う - のようなもの:

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

    foreach(var x in xs.EmptyIfNull()) 
    { 
    ... 
    } 
1

マイクロソフトでは、この(source

public static bool Any<TSource>(this IEnumerable<TSource> source) 
{ 
    if (source == null) throw new ArgumentNullException("source"); 
    using (IEnumerator<TSource> e = source.GetEnumerator()) 
    { 
     if (e.MoveNext()) return true; 
    } 
    return false; 
} 
のように「)( `どれを実装しました

コールスタックにコールを保存する場合は、!Any()を呼び出す拡張メソッドを書き込むのではなく、次の3つの変更を書き換えてください。

public static bool IsEmpty<TSource>(this IEnumerable<TSource> source) //first change (name) 
{ 
    if (source == null) throw new ArgumentNullException("source"); 
    using (IEnumerator<TSource> e = source.GetEnumerator()) 
    { 
     if (e.MoveNext()) return false; //second change 
    } 
    return true; //third change 
} 
1

リストにEnumerable.Empty<T>()を使用することには欠点があります。 Enumerable.Empty<T>をリストコンストラクタに渡すと、サイズ4の配列が割り当てられます。しかし、空のCollectionをリストコンストラクタに渡すと、割り当ては行われません。したがって、コード全体でこのソリューションを使用すると、おそらくIEnumerableのうちの1つがリストの作成に使用され、不要な割り当てが行われます。

関連する問題