如何编写一个接受一系列匿名字典项的API?

时间:2011-01-11 18:58:12

标签: c# dictionary anonymous-types

我经常发现自己需要编写涉及键值对的API,当我使用它时,我最终会得到一个List<KeyValuePair<string,string>>或类似的类型集合对象,这样我就可以非常轻松地编写操作。

我遇到的唯一缺点是在此收集中添加多个项目通常会产生非常嘈杂的代码块,例如

MyDictionary.Put(new KeyValuePair<string, string>("a","1"), 
                 new KeyValuePair<string, string>("b","2"), 
                 new KeyValuePair<string, string>("c","3"))

我宁愿能够做到

MyDictionary.Put( {"a","1"},  {"b","2"},  {"c","3"})

有几次我试图完成并总是最终绊倒C#所期望的语法。

4 个答案:

答案 0 :(得分:4)

集合初始化程序允许其中的大部分内容;

var data = new Dictionary<string,string> {
    {"a","1"},
    {"b","2"},
    {"c","3"}
};

另一种解决方法是仅传递object使用反射,传递(例如):

new { a = "1", b = "2", c = "3" }

最后一个选项的一个不错的功能是您也可以传入您的域实体,也可以使用更丰富的元数据(属性等) - 但用于高容量反射除非您采取措施对其进行优化,否则本身可能会很慢。如果您没有在紧密循环中使用它,即使使用反射(并且没有优化)也应该没问题。

答案 1 :(得分:1)

对于文字,怎么样......

MyDictionary.Put("a=1", "b=2", "c=3");

实施了类似......

void Put(params string[] nameEqualValues)
{
    foreach (string nameEqualValue in nameEqualValues)
    {
        int iEquals = nameEqualValue.IndexOf('=');
        if (iEquals < 0)
        {
            throw new ApplicationException(...);
        }
        string name = nameEqualValue.Substring(0, iEquals);
        string val = nameEqualValue.Substring(iEquals + 1);

        this.PutNameValue(name, val);
    }
}

组合然后拆分字符串有点开销,但听起来不像是性能是一个关键问题。

请注意,如果你没有处理文字,这会比你开始时更糟糕......

MyDictionary.Put(d + "=" + x, e + "=" + y);
MyDictionary.Put(String.Format("{0}={1}", d, x), ...);

我可能会把它吸干并坚持使用“params string []”,或者多次调用Put。 (或使用python;)

答案 2 :(得分:1)

要求params成对出现并将evens(零,二,......)作为键和赔率处理为值:

void Put(params string[] items)
{
    if (items.Length % 2 != 0) throw new ArgumentException("Expected even number");

    for (int i = 0; i < items.Length; i += 2)
    {
        this.myDict[items[i]] = items[i+1];
    }
}

答案 3 :(得分:1)

我无法弄清楚这样做的一种非常干净的方法,但是对于较小的打字,可以采用以下方法:

public class MyDictionary : List<KeyValuePair<string, string>>
{
    ...

    public void Put(params string[][] p)
    {
        foreach (var a in p)
            Add(new KeyValuePair<string, string>(a[0], a[1]));
    }
}

可以像这样调用:

MyDictionary.Put(new[] {"a", "1"}, new[] {"b", "2"}, new[] {"c", "3"});

但这是一种明确的内存浪费,也是非常低效的编码。