web-dev-qa-db-ja.com

匿名型リストの宣言

匿名型のリストオブジェクトを宣言する方法はありますか。というのは

List<var> someVariable = new List<var>();
someVariable.Add(
             new{Name="Krishna", 
                 Phones = new[] {"555-555-5555", "666-666-6666"}}
                );

これは、実行時にコレクションを作成する必要があるためです。

74
Krishna

少しハッカーが必要ですが、実行できます。

static List<T> CreateListFromSingle<T>(T value) {
  var list = new List<T>();
  list.Add(value);
  return list;
}

var list = CreateListFromSingle(
   new{Name="Krishna", 
                 Phones = new[] {"555-555-5555", "666-666-6666"}}
                );
60
JaredPar

ダイナミックはどうですか?

List<dynamic> dynamicList = new List<dynamic>();


dynamicList.Add(new { Name = "Krishna",  Phones = new[] { "555-555-5555", "666-666-6666" } }); 
78
Jai Kannah

このようなリストを作成することもできますが、深刻なハッカーを使用する必要があり、「タイプごとの」状況を使用する必要があります。例えば:

// create the first list by using a specific "template" type.
var list = new [] { new { Name="", Phones=new[] { "" } } }.ToList();

// clear the list.  The first element was just an example.
list.Clear();

// start adding "actual" values.
list.Add(new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } });
53
David Morton

一般的に、他の人が言及した例のトリックによる(おそらく悪臭)キャストを使用して、型引数に匿名型でパラメーター化されたジェネリック型のインスタンスを作成できます。ただし、List<T>それを行うための少し粗雑な方法があります:

var array = new[] {
  new {  
    Name="Krishna",  
    Phones = new[] {"555-555-5555", "666-666-6666"}
  }
};
var list = array.ToList();

提案された構文のスケッチは、C#3または4用に実装しなかった機能に似ていますが、検討しました。この機能は「mumble types」と呼ばれ、次のようになります。

List<?> myList = new List<?>() {
  new {  
    Name="Krishna",  
    Phones = new[] {"555-555-5555", "666-666-6666"}
  }
};

もちろん、「myListはhrmmfの新しいリストです」と読むため、「mumble types」と呼びます。 :-)

アイデアは、コンパイラがイニシャライザを見て、タイプがどのようなものになる可能性があるかを把握するために最善を尽くすことです。「var」が「イニシャライザを見て変数のタイプ「。 「var」を「mumble」または「?」として使用するかどうか(これはJavaが関連機能で行うことと似ています)、または他の何かが未解決の質問です。

いずれにせよ、私があなただったら、この機能を待つことはありません。これまでのところ、いくつかの言語バージョンを削減していませんが、しばらくは可能性のリストにとどまるでしょう。仮に言えば、言語の将来のバージョンを設計することになっていた場合。私たちはそうかもしれないし、そうでないかもしれない。覚えておいてください、C#の将来のバージョンに関するエリックの黙想は娯楽目的のためだけです。

26
Eric Lippert

このような匿名型のコレクションを作成することはできません。

これを行う必要がある場合は、List<object>を使用するか、型のカスタムクラスまたは構造体を作成する必要があります。


編集:

これを言い換えます:

技術的には、匿名タイプのリストを作成することは可能ですが、これを絶対に行わないことを強くお勧めします。これを行うことは、ほとんど維持不可能なコードを作成するだけなので、ほとんど常により良いアプローチがあります。匿名型を使用する代わりに、値を保持するカスタム型を作成することを強くお勧めします。

カスタム型はすべて同じ機能を備えています(匿名型はコンパイラによってコンパイル時に定義されるため)が、あなたをフォローしている開発者はさらに理解しやすくなります...


また、単に再生するために、「実際の世界では実際に使用したくないコード」のエントリを次に示します。

var customer = new { Name = "Krishna", Phones = new[] { "555-555-5555", "666-666-6666" } };
var someVariable = new[]{1}.Select(i => customer).ToList();
15
Reed Copsey

以下は、他の多くの提案よりもややクリーンなアプローチです。

var list = Enumerable.Repeat(new { Name = "", Phones = new[] { "" } }, 0)
               .ToList();

// ...
list.Add(new { Name = "Krishna", 
               Phones = new[] { "555-555-5555", "666-666-6666" } });
13
Ian Mercer

私は匿名型のリストを使用して時間を節約する方法を見つけるためにかなりの時間を費やし、現在のクラス内でプライベートクラスを使用する方がおそらくもっと速いことに気付きました...

private class Lookup {
    public int Index;
    public string DocType;
    public string Text;
}
private void MyMethod() {
    List<Lookup> all_lookups = new List<Lookup> {
        new Lookup() {Index=4, DocType="SuperView", Text="SuperView XML File"},
        new Lookup() {Index=2, DocType="Word", Text="Microsoft Word Document"}
    };
    // Use my all_lookups variable here...

}
9
Jonathan

これが可能だとは思わない。多分、C#4でdynamicキーワードを使用していますか?

2
Robert Massa