Dictionary <TKey、TValue>エントリにコレクション初期化子を使用できますか?


94

コードの次のビットにコレクション初期化子を使用したいと思います。

public Dictionary<int, string> GetNames()
{
    Dictionary<int, string> names = new Dictionary<int, string>();
    names.Add(1, "Adam");
    names.Add(2, "Bart");
    names.Add(3, "Charlie");
    return names;
}

したがって、通常は次のようになります。

return new Dictionary<int, string>
{ 
   1, "Adam",
   2, "Bart"
   ...

しかし、これの正しい構文は何ですか?


この投稿をチェックしてください:marcin-chwedczuk.github.io/…– csharpfolk 2016
9:01


彼らが略語辞書宣言の構文ではなく、なぜ彼らの(古代の)設定で機能しなかったのかを尋ねていたので、それはだまされているとは思わないでください。
NH。

回答:


157
var names = new Dictionary<int, string> {
  { 1, "Adam" },
  { 2, "Bart" },
  { 3, "Charlie" }
};

1
初期化子はいつ機能しますか?Dictionary<TKey, TValue>サブクラス専用ICollection<KeyValuePair<TKey, TValue>>ですか、それとも機能しますか?
Shimmy Weitzhandler

C#3.0の後に、あなたは使うことができvar宣言する型の代わりに、または宣言する型を残すことは省略することができるかどうかnew Dictio...- stackoverflow.com/questions/5678216/...
drzaus

1
@drzaus:varを使用することは、醜く、醜い習慣です。C#は強く型付けされた言語です。
Nyerguds 2014

1
@Nyerguds:何? var文字通り、キーストロークを節約するだけで、暗黙的に強く型付けされます。
drzaus 14

4
@Nyerguds-あなたはあなたの意見を受け取る資格があると思いますが、変数をすぐに初期化している場合、での使用varと繰り返しで文字通りの違いはありませんSomeType obj = new SomeType...。また、var obj;すぐに初期化しないと宣言できないため、問題は発生しません。ほんとに、勉強しようとしているのですが、あなたの立場は理解できません。
drzaus 14

36

構文は少し異なります:

Dictionary<int, string> names = new Dictionary<int, string>()
{
    { 1, "Adam" },
    { 2, "Bart" }
}

値のタプルを効果的に追加していることに注意してください。

補足として:コレクション初期化子には、基本的に、コンパイル時の引数のタイプに関して便利なAdd()関数への引数である引数が含まれています。つまり、コレクションがある場合:

class FooCollection : IEnumerable
{
    public void Add(int i) ...

    public void Add(string s) ...

    public void Add(double d) ...
}

次のコードは完全に合法です:

var foos = new FooCollection() { 1, 2, 3.14, "Hello, world!" };

正解です。知りませんでした。とにかく、辞書初期化子はいつ機能しますか?これは、Dictionary <TKey、TValue>サブクラスのみに有効ですか、それともICollection <KeyValuePair <TKey、TValue >>でも機能しますか?
Shimmy Weitzhandler

@Shimmyコレクションイニシャライザは、メソッドを実装しIEnumerable 持つすべてのもので機能しAdd()ます。
Anton Gogolev、

@Shimmy:辞書はコレクションである
ジョン・サンダース

@JohnSaundersしかし、辞書初期化子はの2つのパラメータを受け入れますAdd
Shimmy Weitzhandler

2
@シミー:なぜそれが問題なのですか?重要なのは、それが実装し、メソッドを持つすべてのクラスで機能IEnumerable<T>するAddことです。Addメソッドが3つのパラメーターを取る場合、括弧内に3つのオブジェクトが必要になります。
John Saunders、

11
return new Dictionary<int, string>
{ 
   { 1, "Adam" },
   { 2, "Bart" },
   ...

10

質問にはタグが付けられてc#-3.0いますが、完全を期すために、Visual Studio 2015(またはMono 4.0)を使用している場合に備えて、C#6で使用できる新しい構文について説明します。

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie"
};

注:他の回答で言及されている古い構文は、それでもうまく機能する場合でも機能します。ここでも、完全を期すために、古い構文を次に示します。

var dictionary = new Dictionary<int, string>
{
   { 1, "Adam" },
   { 2, "Bart" },
   { 3, "Charlie" }
};

注意すべきもう1つの種類の優れた点は、どちらの構文でも、必要に応じて最後のコンマを残すことができるため、追加の行のコピー/貼り付けが簡単になることです。たとえば、次のコードは問題なくコンパイルされます。

var dictionary = new Dictionary<int, string>
{
   [1] = "Adam",
   [2] = "Bart",
   [3] = "Charlie",
};

5

少し冗長な構文を探している場合は、次のDictionary<string, object>ような(またはタイプが何であれ)サブクラスを作成できます。

public class DebugKeyValueDict : Dictionary<string, object>
{

}

次に、このように初期化します

var debugValues = new DebugKeyValueDict
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });

これは

var debugValues = new Dictionary<string, object>
                  {
                       { "Billing Address", billingAddress }, 
                       { "CC Last 4", card.GetLast4Digits() },
                       { "Response.Success", updateResponse.Success }
                  });

あなたが言うことができるようなあなたが望むかもしれないすべてのコンパイルタイプのものを得るという利点

is DebugKeyValueDict の代わりに is IDictionary<string, object>

または、後でキーまたは値のタイプを変更する。かみそりのcshtmlページ内でこのようなことをしている場合は、見た目がずっと良くなります。

冗長ではないだけでなく、必要に応じてこのクラスにメソッドを追加することもできます。


- ViewDataDictionaryはMVCでどのように動作するかこれは基本的にstackoverflow.com/questions/607985/...
Simon_Weaver

辞書と型付き配列の 'エイリアス'として型を実験しましたが、型付きの世界では、定義済みの型を使用する方が安全だと思いました。
Patrick

1

次のコード例でDictionary<TKey, TValue>は、a はタイプのインスタンスで初期化されていますStudentName

  Dictionary<int, StudentName> students = new Dictionary<int, StudentName>()
  {
      { 111, new StudentName {FirstName="Sachin", LastName="Karnik", ID=211}},
      { 112, new StudentName {FirstName="Dina", LastName="Salimzianova", ID=317}},
      { 113, new StudentName {FirstName="Andy", LastName="Ruth", ID=198}}
  };

MSDNから


-3

はい、辞書でコレクション初期化子を使用できます。このような辞書がある場合、

Dictionary<int,string> dict = new Dictionary<int,string>();  
            dict.Add(1,"Mohan");  
            dict.Add(2, "Kishor");  
            dict.Add(3, "Pankaj");  
            dict.Add(4, "Jeetu");

以下のように初期化できます。

Dictionary<int,string> dict = new Dictionary<int,string>  
            {  

                {1,"Mohan" },  
                {2,"Kishor" },  
                {3,"Pankaj" },  
                {4,"Jeetu" }  

            }; 

4
これを行う方法を示す他の回答はすでに6つあります。同じことを示す7番目の回答は必要ありません。
サービー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.