буквальная нотация для словаря в c #?

<p>вы используете синтаксис <a href="https://msdn.microsoft.com/en-us/library/bb384062.aspx">инициализатор коллекции</a> , но вам все равно нужно сначала создать объект <code>new dictionary<string, string></code>, так как синтаксис ярлыка преобразуется в набор вызовов <code>add()</code> (например, ваш код):</p><pre><code>var data = new dictionary<string, string> { { "test", "val" }, { "test2", "val2" } }; </code></pre><p>в c # 6 теперь у вас есть возможность использовать более интуитивный синтаксис со словарем, а также любой другой тип, который поддерживает <a href="https://msdn.microsoft.com/en-us/library/6x16t2tx.aspx">indexers</a> . вышеприведенное утверждение можно переписать так:</p><pre><code>var data = new dictionary<string, string> { ["test"] = "val", ["test2"] = "val2" }; </code></pre><p>в отличие от инициализаторов коллекций, это вызывает установщик индексатора изнутри, а не соответствующий метод <code>add()</code>.</p>

<p>хотя ответ инициализатора словаря является полностью правильным, есть другой подход, на который я хотел бы обратить внимание (но я бы не рекомендовал его). если ваша цель - обеспечить краткое использование api, вы можете использовать анонимные объекты.</p><pre><code>var data = new { test1 = "val", test2 = "val2"}; </code></pre><p>в этом случае переменная "data" имеет "невыразимый" анонимный тип, так что вы можете передать это только как <code>system.object</code>. затем вы можете написать код, который может преобразовать анонимный объект в словарь. такой код будет опираться на рефлексию, которая потенциально будет медленной. однако вы можете использовать <code>system.reflection.emit</code> или <code>system.linq.expressions</code> для компиляции и кэширования делегата, который сделает последующие вызовы намного быстрее.</p><p>api mvc asp.net используют эту технику во многих местах, которые я видел. многие помощники html имеют перегрузки, которые принимают либо объект, либо словарь. я предполагаю, что цель их api-дизайна такая же, как и вы; краткий синтаксис при вызове метода.</p>

<p>используя <code>dynamicobject</code>, не так сложно создать простой инициализатор словаря.</p><p>представьте, что вы хотите вызвать следующий метод</p><pre><code>void printdict(idictionary<string, object> dict) { foreach(var kv in dict) { console.writeline (" -> " + kv.key + " = " + kv.value); } } </code></pre><p>используя буквальный синтаксис, такой как</p><pre><code>var dict = dict (hello: "world", iam: "a dictionary"); printdict (dict); </code></pre><p>это может быть достигнуто путем создания такого динамического объекта</p><pre><code>dynamic dict { get { return new dynamicdictfactory (); } } private class dynamicdictfactory : dynamicobject { public override bool tryinvoke (invokebinder binder, object[] args, out object result) { var res = new dictionary<string, object> (); var names = binder.callinfo.argumentnames; for (var i = 0; i < args.length; i++) { var argname = names [i]; if(string.isnullorempty(argname)) throw new argumentexception(); res [argname] = args [i]; } result = res; return true; } } </code></pre>

<h1>используйте словарь литералов (предложение c # 9)</h1><p>в c # 9 введен более простой синтаксис для создания инициализированных объектов <code>dictionary<tkey,tvalue></code> без необходимости указывать имя типа словаря или параметры типа. параметры типа для словаря выводятся с использованием существующих правил, используемых для вывода типа массива.</p><pre><code>// c# 1..8 var x = new dictionary <string,int> () { { "foo", 4 }, { "bar", 5 }}; // c# 9 var x = ["foo":4, "bar": 5]; </code></pre><p>этот synthax упрощает работу со словарями в c # и убирает лишний код.</p><p>вы можете следить за этой проблемой на <a href="https://github.com/dotnet/csharplang/issues/414">github</a> (а вот <a href="https://github.com/dotnet/csharplang/milestone/15">веха для c # 9</a> ).</p>