Буквальная нотация для словаря в C #? - PullRequest
161 голосов
/ 12 февраля 2011

В настоящее время у меня есть WebSocket между JavaScript и сервером, запрограммированным на C #.В JavaScript я могу легко передавать данные, используя ассоциативный массив:

var data = {'test': 'val',
            'test2': 'val2'};

Для представления этого объекта данных на стороне сервера я использую Dictionary<string, string>, но это более «дорого печатает», чем вJavaScript:

Dictionary<string, string> data = new Dictionary<string,string>();
data.Add("test", "val");
data.Add("test2", "val2");

Есть ли какая-нибудь буквальная запись для ассоциативных массивов / Dictionary s в C #?

Ответы [ 4 ]

264 голосов
/ 12 февраля 2011

Вы используете синтаксис инициализатора коллекции , но вам все равно нужно сначала создать объект new Dictionary<string, string>, так как синтаксис ярлыка преобразуется в группу вызовов Add() (например, ваш код):

var data = new Dictionary<string, string>
{
    { "test", "val" }, 
    { "test2", "val2" }
};

В C # 6 у вас теперь есть возможность использовать более интуитивный синтаксис со словарем, а также любой другой тип, который поддерживает индексаторы .Вышеприведенное утверждение можно переписать так:

var data = new Dictionary<string, string>
{
    ["test"] = "val",
    ["test2"] = "val2"
};

В отличие от инициализаторов коллекций, это вызывает установщик индексатора под капотом, а не соответствующий метод Add().

12 голосов
/ 03 февраля 2015

Хотя ответ инициализатора словаря является полностью правильным, есть другой подход, на который я хотел бы обратить внимание (но я бы не рекомендовал его).Если ваша цель - обеспечить краткое использование API, вы можете использовать анонимные объекты.

var data = new { test1 = "val", test2 = "val2"};

В этом случае переменная «data» имеет «невыразимый» анонимный тип, так что вы можете передать это только как System.Object.Затем вы можете написать код, который может преобразовать анонимный объект в словарь.Такой код будет опираться на рефлексию, которая потенциально будет медленной.Однако вы можете использовать System.Reflection.Emit или System.Linq.Expressions для компиляции и кэширования делегата, который будет выполнять последующие вызовы намного быстрее.

API-интерфейсы Asp.net MVC используют эту технику в ряде мест, которые явидел.Многие помощники HTML имеют перегрузки, которые принимают либо объект, либо словарь.Я предполагаю, что цель их API-дизайна такая же, как и вы;краткий синтаксис при вызове метода.

6 голосов
/ 09 сентября 2015

Используя DynamicObject, не так сложно создать простой инициализатор словаря.

Представьте, что вы хотите вызвать следующий метод

void PrintDict(IDictionary<string, object> dict) {
    foreach(var kv in dict) {
        Console.WriteLine ("  -> " + kv.Key + " = " + kv.Value);
    }
}

, используя буквальный синтаксис, такой как

var dict = Dict (Hello: "World", IAm: "a dictionary");
PrintDict (dict);

Этого можно достичь, создав такой динамический объект

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;
    }
}
0 голосов
/ 31 мая 2019

Использовать литералы словаря (предложение C # 9)

C # 9 вводит более простой синтаксис для создания инициализированных Dictionary<TKey,TValue> объектов без указания имени типа словаря или параметров типа.Параметры типа для словаря выводятся с использованием существующих правил, используемых для вывода типа массива.

// C# 1..8    
var x = new Dictionary <string,int> () { { "foo", 4 }, { "bar", 5 }};   
// C# 9    
var x = ["foo":4, "bar": 5];  

Этот синтаксис упрощает работу со словарями в C # и удаляет избыточный код.

Youможет следить за проблемой на GitHub (и вот веха для C # 9 ).

...