3

オープンソース プロジェクトで次の方法を見つけました。

    static IEnumerable<T> Cat<T>(T t) {
        yield return t;
    }

私が理解している限り、それはIEnumerable<T>含むを返す以外に何もしませんt。私が正しく、それがたとえばと仮想的に同等である場合、ここreturn new List<T>{t};で使用する目的/利点は何ですか? yield returnそして、私が間違っているとしたら、何が欠けているのでしょうか?

完全なソースはここにあります

4

3 に答える 3

5

これは、単一の要素 ( ) を含む列挙型を作成するだけtです。実際には、あなたは正しいです。事実上、List<T>1 つの要素を持つ new や 1 つの要素を持つ新しい配列などを返すのと非常によく似ています。

主な違いは、返される型が実際には aList<T>または配列ではなく、コンパイラによって生成された型になることです。たとえば、結果をリストにキャストして要素を追加することはできません。実際には、説明したように new を返すのと同じように動作しList<T>ます。

開発者がおそらくこの構文を好んでいたことを除けば、本当の利点はおそらくありません。私はおそらく、単一の要素がIEnumerable<T>が渡されることを期待する API の他の部分と連携できるようにするために使用されたのではないかと思いますが、メソッド名には少し不満があります、IMO.

于 2012-09-24T18:52:40.743 に答える
3

実際のコレクションを返すことと使用することの違いは、yield返すオブジェクトの型だけです。

を実装するコレクションを返す場合IEnumerable<T>、返されるオブジェクトの実際の型はその型になります。たとえば、 を返す場合、List<T>返される参照はIEnumerable<T>型になりますが、参照が指すオブジェクトの実際の型は のインスタンスですList<T>

を使用するyieldと、コンパイラは既知の名前のない列挙子オブジェクトを作成します。返される参照の型も になりIEnumerable<T>ますが、参照が指すオブジェクトの実際の型は、コンパイラが作成するものになります。

たとえば、整数に対して作成された列挙子の型の名前を取得します。

Console.WriteLine(Cat<int>(42).GetType().Name);

たとえば、コードから得た次の結果など、コンパイラが使用する内部名が表示されます。

<Cat>d__5`1

関数がList<int>代わりに a を返す場合、型は次のように表示されます。

List`1

コンパイラにこれの列挙子を作成させる動機は、おそらく次のようなものよりも短いということです。

static IEnumerable<T> Cat<T>(T t) {
  List<T> list = new List<T>(1);
  list.Add(t);
  return list;
}

(C# の新しいバージョンでは、ショートカットを使用して少し短く書くことができますが、それでもyield.

型がコレクションの場合、参照を実際の型にキャストして、コレクション内の値を変更できます。

IEnumerable<int> ienum = Cat<int>(42);

((List<int>)ienum)[0] = 1337;

foreach (int value in ienum) {
  Console.WriteLine(value);
}

出力します:

1337
于 2012-09-24T18:58:47.917 に答える
0

この関数は、列挙型があり、1 つの項目を追加する場合に、単一の項目を列挙型に変換します。次に例を示します。

 IEnumerable<someType> Columns;

 var headers = String.Join(",", Columns.Select(c => c.Name).Concat(new string[] { "Last Column" }));

書いたほうがいい

 var headers = String.Join(",", Columns.Select(c => c.Name).Concat(Cat("Last Column")));
于 2012-09-24T18:55:39.930 に答える