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

В настоящее время у меня есть WebSocket между JavaScript и сервером, запрограммированным на С#. В 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 в С#?

4b9b3361

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

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

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

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

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

193
ответ дан 12 февр. '11 в 23:42
источник

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

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

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

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

8
ответ дан 03 февр. '15 в 21:08
источник

Используя 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;
    }
}
3
ответ дан 09 сент. '15 в 0:32
источник