我喜欢元组.它们允许您快速将相关信息分组在一起,而无需为其编写结构或类.这在重构非常本地化的代码时非常有用.
然而,初始化它们的列表似乎有点多余.
var tupleList = new List<Tuple<int, string>>
{
Tuple.Create( 1, "cow" ),
Tuple.Create( 5, "chickens" ),
Tuple.Create( 1, "airplane" )
};
Run Code Online (Sandbox Code Playgroud)
有没有更好的方法?我希望得到一个类似于字典初始化器的解决方案.
Dictionary<int, string> students = new Dictionary<int, string>()
{
{ 111, "bleh" },
{ 112, "bloeh" },
{ 113, "blah" }
};
Run Code Online (Sandbox Code Playgroud)
我们不能使用类似的语法吗?
在最近出现了很多讨论关于C#什么新的6.0
的一个最受关注的功能是通过Dictionary在初始化C#6.0
别急,我们一直在使用集合初始化器来初始化集合,并可以很好的初始化Dictionary也.NET 4.0和.NET 4.5(不知道旧版本)之类的
Dictionary<int, string> myDict = new Dictionary<int, string>() {
{ 1,"Pankaj"},
{ 2,"Pankaj"},
{ 3,"Pankaj"}
};
Run Code Online (Sandbox Code Playgroud)
那么C#6.0中有什么新东西,他们在C#6.0中讨论的是什么字典初始化器
MSDN声明:
通过使用集合初始值设定项,您不必在源代码中指定对类的Add方法的多个调用; 编译器添加调用.
他们也给出了这个例子,使用带括号的更新的集合初始化语法:
var numbers = new Dictionary<int, string> {
[7] = "seven",
[9] = "nine",
[13] = "thirteen"
};
Run Code Online (Sandbox Code Playgroud)
但是,在检查生成的IL代码时,似乎这段代码根本不会导致对该Add方法的任何调用,而是对一个调用set_item,例如:
IL_0007: ldstr "seven"
IL_000c: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::set_Item(!0/*int32*/, !1/*string*/)
Run Code Online (Sandbox Code Playgroud)
相反,带有大括号的"旧"语法给出以下内容:
// C# code:
var numbers2 = new Dictionary<Int32, String>
{
{7, "seven"},
{9, "nine"},
{13, "thirteen"}
};
// IL code snippet:
// ----------
// IL_0033: ldstr "seven"
// IL_0038: callvirt instance void class [mscorlib]System.Collections.Generic.Dictionary`2<int32, string>::Add(!0/*int32*/, !1/*string*/)
Run Code Online (Sandbox Code Playgroud)
......正如您所看到Add的,正如预期的那样,调用结果就是结果.(人们只能假设上面提到的MSDN上的文本尚未更新.)
到目前为止,我发现了一个这种差异实际上很重要的案例,那就是古怪System.Collections.Specialized.NameValueCollection …
在字典初始值设定项中,有两种方法可以使用内容创建字典:
new Dictionary<string, GradientSpace>
{
["userSpaceOnUse"] = GradientSpace.Absolute,
["objectBoundingBox"] = GradientSpace.Relative
})
Run Code Online (Sandbox Code Playgroud)
和
new Dictionary<string, GradientSpace>
{
{"userSpaceOnUse", GradientSpace.Absolute},
{"objectBoundingBox", GradientSpace.Relative}
});
Run Code Online (Sandbox Code Playgroud)
在这两种语法中是否存在任何差异,或者仅仅是偏好问题?