C# 字典初始值设定项的类型

C# 字典初始值设定项的类型,c#,dictionary,C#,Dictionary,我有以下代码: class Program { static void Main(string[] args) { var a = new Dictionary<string, int>() { { "12", 12 }, { "13", 13 }, }; } static object Fifteen() { //return n

我有以下代码:

class Program
{
    static void Main(string[] args)
    {
        var a = new Dictionary<string, int>()
        {
            { "12", 12 },
            { "13", 13 },
        };
    }

    static object Fifteen()
    {
        //return new object[] { "15", 15 };
        return new {key = "15", value = 15};
    }
}

L.E.编译错误是:
错误CS7036:没有给出与“Dictionary.Add(string,int)”的必需形式参数“value”对应的参数,这是不可能的。字典初始值设定项是语法糖。所以你的代码

var a = new Dictionary<string, int>()
{
    { "12", 12 },
    { "13", 13 },
};
var a=newdictionary()
{
{ "12", 12 },
{ "13", 13 },
};
实际上被翻译为:

var tmp = new Dictionary<string, int>();
tmp.Add("12", 12);
tmp.Add("13", 13};
var a = tmp;
var tmp=newdictionary();
tmp.添加(“12”,12);
tmp.Add(“13”,13};
var a=tmp;
因此元素被用作
Add
的参数。即使
十五()
将返回
KeyValuePair
编译器仍将缺少适当的
Add
方法


(但如图所示,您可以提供一个扩展名
Add
方法来实现此功能)

您需要更改
十五个
方法,使其返回一个
KeyValuePair
,而不是
对象
,以便该方法的调用者可以访问您提供的数据(仅当匿名类型在创建它们的相同方法中使用时,才应使用它们):


之后,您所述的代码就可以编译并正常运行。

不行,初始化器不会这样工作。
字典上只有一个
Add
方法,它只需要两个参数。如果有一个重载需要一个
KeyValuePair
,您可以使用它,但没有。@jeroemostert,在c#6.0中是be可以使用扩展方法
Add
和集合初始值设定项。我们可以在C#7中进一步使用
ValueTuple
;这样
十五个
就可以像
静态(字符串,int)十五个()=>(“15”,15)一样简单
。@jeroemostert的回答很好,推荐也很好。我有点讨厌这种“魔法”对于香草
字典
初始值设定项来说,语法上的甜头,但是看到人们能想出的规范化语法的方法,这很酷。@foxx1337我不会真的称之为对接受键值对的字典使用
Add
方法的黑客行为。这是一种语义上合适的操作,类型可以e、 这不是一个概念上没有意义的不恰当的方法。另一方面,通过使用元组来剥离类型命名,仅仅期望人们知道事情的含义,这确实会让你进入黑客和魔法的领域,因为代码用户必须拥有代码本身中没有传达的信息。@Servy:幸运的是,没有阻止我们写入
(字符串键,int值)十五()=>(“15”,15);
(甚至
(字符串键,int值)十五()=>(键:“15”,值:15);
,如果您想真正显式);该语言为标记
ValueTuple
成员提供了良好的支持,即使名称在概念上不是类型的一部分。@这里我的意思是
{}
结构“覆盖”了一系列
Add()
无法通过C#的类型系统表示的操作。因此,您提出了一种巧妙的解决方法。我希望最里面的大括号中的内容可以表示为一些
CollectionElementAtomTuple
类型,而不仅仅是编译器将其转换为一系列方法调用。
var tmp = new Dictionary<string, int>();
tmp.Add("12", 12);
tmp.Add("13", 13};
var a = tmp;
static KeyValuePair<string, int> Fifteen()
{
    return new KeyValuePair<string, int>("15", 15);
}
public static void Add<TKey, TValue>(this Dictionary<TKey, TValue> dictionary, KeyValuePair<TKey, TValue> pair)
{
    dictionary.Add(pair.Key, pair.Value);
}