web-dev-qa-db-ja.com

C#に「空のリスト」シングルトンはありますか?

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

ただし、多くの場合、デフォルトとして空の_IEnumerable<X>_が必要であることがわかります。つまり、私はしたい

_for (var x in xs) { ... }
_

nullチェックを必要とせずに動作します。今、これはより大きなコンテキストに応じて私が現在していることです:

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

さて、上記は私にとっては完全に問題ありませんが-つまり、配列オブジェクトIただ気にしない-私は疑問に思っていました:

C#/。NETに「空の不変のIEnumerable/IList」シングルトンはありますか?(そうでない場合でも、「より良い」処理方法があります上記の場合?)

Javaには _Collections.EMPTY_LIST_ 不変のシングルトン- Collections.emptyList<T>() を介して "well-typed"があります。ジェネリックは異なる方法で処理されるため、同様の概念がC#でも機能する場合。

ありがとう。

64
user166390

Enumerable.Empty<int>();を探しています

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

82
Stilgar

Enumerable.Empty<T>() はまさにそれです。

50
Jon

Enumerable.Empty<T>() を探していると思います。

リストは可変であることが多いため、空のリストシングルトンはあまり意味がありません。

18
svick

拡張メソッドを追加することは、nullを処理する機能のおかげで、きれいな代替手段だと思います-

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

  foreach(var x in xs.EmptyIfNull())
  {
    ...
  }
10
Andrew Hanlon

元の例では、空の配列を使用して空の列挙型を提供します。 Enumerable.Empty<T>()を使用することは完全に正しいですが、他の場合もあります。使用する必要がある配列(またはIList<T>インターフェイス)、メソッドを使用できます

System.Array.Empty<T>()

これにより、不要な割り当てを回避できます。

注/参照:

7
ventiseis

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

1
sjb-sjb

Microsoftはこのように「Any()」を実装しました( 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
user2023861