C#で "空リスト"シングルトンがありますか?

C#ではLINQとIEnumerableを使います。そして、すべてが善良で(または少なくともほとんどそうです)。

However, in many cases I find myself that I need an empty IEnumerable as a default. That is, I would like

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

上のコードは完全にうまくいくですが、配列オブジェクトを作成する際に "余分なオーバーヘッド"がある場合は、気にしないでください私は考えていた:

Is there "empty immutable IEnumerable/IList" singleton in C#/.NET? (And, even if not, is there a "better" way to handle the case described above?)

Java has Collections.EMPTY_LIST immutable singleton -- "well-typed" via Collections.emptyList() -- which serves this purpose, although I am not sure if a similar concept could even work in C# because generics are handled differently.

ありがとう。

59
public static class Array {public static readonly T [] Empty =新しいT [0]; } であり、 Array .Empty のように呼び出すことができます。私は CodeReview でこれについて尋ねました。
追加された 著者 Şafak Gür,
まあ、こんにちは:)これは私がリスト/ IListとEnumerable/IEnumerableではなく、すべての投票にすべての感謝に焦点を当てるものです。
追加された 著者 user166390,
追加された 著者 user166390,

7 答え

You are looking for Enumerable.Empty();

他のニュースでは、Listのインターフェースがリストに要素を追加して例外をスローするメソッドを公開しているので、Javaの空のリストは嫌です。

72
追加された
副次的に、すべての配列はC#のIList です。これは、新しい項目を追加しようとするとスローされます。
追加された 著者 Grzenio,
また、他の人たちはより多くのアップフォースを手に入れました。私は質問を投稿しますが、私は今すぐ寝るつもりで、私はその質問に従うことができません。なぜ自分で投稿するのですか?
追加された 著者 Stilgar,
IEnumerable ではなく)何らかのリストを必要とする理由は、実現されていて(遅延実行なし)、既知のカウントします。この場合、 IReadOnlyCollection を使用する必要があります。インデックス化されたアクセスが必要な場合は、 IReadOnlyList があります。
追加された 著者 Timo,
クラスメソッドは List (インデックスでアクセスできるコレクション)を返す必要があるかもしれないからです。これらの List は読み込み専用です。そして、いつも、そのような読み込み専用の List をゼロ要素で返す必要があります。したがって、 Collections.emptyList()メソッド。実装されたインタフェースは、メソッドがリストを返すように指定するため、空のIterableを返すことはできません。大きな問題は、あなたが返すことができるImmutableListインターフェイスがないことです。同じ問題が.NETにあります:すべての IList は読み込み専用です。
追加された 著者 Laurent Bourgault-Roy,
それは非常に有効なポイントです!おそらくそれは新しいSOの質問を保証するでしょうか?
追加された 著者 user166390,
あなたは数秒遅く、ドキュメンテーションのリンクもありませんでした。しかし、あなたはsvicksのコメントを拡大して受け入れることができます。 * finger shake * ;-)
追加された 著者 user166390,
あなたがそれを指摘して以来、明らかになっているように思えるので、= ^ _ ^ =
追加された 著者 user166390,
関数は、次のようにして、リスト内のすべての要素を削除します。 }
追加された 著者 Rodrigo Quesada,
例外をスローすることと読み取り専用のインタフェースを比較する〜=実行時にエラーを受け取ることとコンパイル時に取得することとの違い私は間違いなく、リストのための読み取り専用のインターフェイスを定義するJava仕様を好むだろうが、それは残念ながらそうではありません。
追加された 著者 Rodrigo Quesada,

Enumerable.Empty() is exactly that.

45
追加された
@Timoのこの質問とこれを含む多くの答えは、 Array.Empty が利用可能になるまでに約3年前に書かれました。 :)いずれの場合でも、タイトルにもかかわらず、この質問は、 IEnumerable が目的に適していることを明示的に明確にしています。
追加された 著者 Jon,
まあ、正確にではありません。 :) Array.Empty ()は、 IList であるため、 "list"の入力が求められています。 IReadOnlyCollection を満足させることも幸いです。もちろん、 IEnumerable で十分であれば、 Enumerable.Empty ()は完全に適合します。
追加された 著者 Timo,

I think you're looking for Enumerable.Empty().

空リストのシングルトンはあまり意味がありません。リストはしばしば変更可能です。

17
追加された

私は、拡張メソッドを追加することは、ヌルを処理する能力のおかげできれいな選択肢だと思います。

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

  foreach(var x in xs.EmptyIfNull())
  {
    ...
  }
10
追加された

In your original example you use an empty array to provide an empty enumerable. While using Enumerable.Empty() is perfectly right, there might other cases: if you have to use an array (or the IList interface), you can use the method

System.Array.Empty()

不要な割り当てを避けることができます。

ノート/参照:

2
追加された

MicrosoftはこのようなAny()を実装しました(ソース

public static bool Any(this IEnumerable source)
{
    if (source == null) throw new ArgumentNullException("source");
    using (IEnumerator e = source.GetEnumerator())
    {
        if (e.MoveNext()) return true;
    }
    return false;
}

呼び出しスタックに呼び出しを保存する場合、!Any()を呼び出す拡張メソッドを記述するのではなく、次の3つの変更を書き直すだけです。

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

Using Enumerable.Empty() with lists has a drawback. If you hand Enumerable.Empty into the list constructor then an array of size 4 is allocated. But if you hand an empty Collection into the list constructor then no allocation occurs. So if you use this solution throughout your code then most likely one of the IEnumerables will be used to construct a list, resulting in unnecessary allocations.

1
追加された