4

今日、いくつかのランダムなオブジェクトの作成を通じて、このDictionary<K, V>. 次の割り当てはコンパイラのショートカットですか、それとも の機能ですかDictionary<string, string>

IDictionary<string, string> items = { { "item1key", "item1value" } };

ソースを見ると、Dictionary<K, V>これがどのように機能するかについて、手に負えないものは何もありません。このクラス ドットのすべてのインターフェイスを実装しても、同様の操作を実行することはできません。辞書にはできるのに、別の型にはできないのはなぜですか。たとえば、コンパイラまたは言語機能は、最初の項目がキーで 2 番目の項目が値であることをどのように認識しますか。または、さらに具体的には、この同じ構文を使用することはできませんList<string>

List<string> items = { "item1" };

最初のものは有効ですが、なぜですか?

私は必ずしもこれを複製しようとしているわけではありませんが、なぜそうなのかについて興味があります。この場合、辞書が特別な理由は何ですか?

うまくいく例

public class Button
{
    public string Title { get; set; }
    public ButtonType Type { get; set; }
    public IDictionary<string, string> Items { get; set; }
    public bool RequiresSelected { get; set; }
}

var buttons = new List<Button>
    {
        new Button { 
            Items = {
                        {"button1", "Button 1"},
                        {"button2", "Button 2"},
                        {"button3", "Button 3"},
                    }, 
            Title = "3 Buttons", 
            Type = ButtonType.DropDown 
        }
    };
4

2 に答える 2

7

あなたが示した構文は、C# では有効ではありません。必要なもの:

IDictionary<string, string> items = new Dictionary<string, string>
    { { "item1key", "item1value" } };

その時点では、それは単なる通常のコレクション初期化子であるため、同等のリストは次のようになります。

List<string> items = new List<string> { "item1" };

編集: 私の編集があなたの編集に勝るか見てみましょう。私の推測では、あなたは次のようなものを見たことがあるでしょう:

var foo = new Foo {
    SomeDictionaryProperty = { 
         { "item1key", "item1value" }
    }
};

これは組み込みのコレクション初期化子であり、リストにも使用できます。新しい辞書を作成するのではなく、既存の辞書に追加します。上記のコードは次と同等です。

var tmp = new Foo();
tmp.SomeDictionaryProperty.Add("item1key", "item1value");
var foo = tmp;

それが機能する別の例:

var form = new Form {
    Controls = { new Label { Text = "Foo"}, new Label { Text = "Bar" } }
};

詳細については、C# 4 仕様 (オブジェクト初期化子) のセクション 7.6.10.2 を参照してください。重要な点は次のとおりです。

member-initializer:
    identifier   =   initializer-value

initializer-value:
    expression
    object-or-collection-initializer

そのため、プロパティを特定の値 (この場合はセッターが使用されます)またはオブジェクト/コレクション初期化子を介して初期化できます。この場合、プロパティのゲッターが使用され、次にセッターまたは Add メソッドが使用されますオブジェクト/コレクション初期化子の本体に使用できます。

于 2012-05-03T20:46:48.323 に答える
2

これは C# コンパイラの機能であり、ディクショナリは特別なものではありません。サポートするコレクションはすべてAdd、この方法で初期化できます。詳細は、C# 言語仕様 4.0のセクション 7.6.10.3 にあります。

コレクション初期化子が適用されるコレクション オブジェクトは、System.Collections.IEnumerable を実装する型である必要があります。そうしないと、コンパイル時エラーが発生します。指定された要素ごとに、コレクション初期化子は、要素初期化子の式リストを引数リストとしてターゲット オブジェクトの Add メソッドを呼び出し、呼び出しごとに通常のオーバーロード解決を適用します。したがって、コレクション オブジェクトには、要素初期化子ごとに適用可能な Add メソッドが含まれている必要があります。

于 2012-05-03T20:51:34.427 に答える