我认为这是我第一次使用新的C#6字典初始化功能,我需要一个如下所示的嵌套结构:
var map = new Dictionary<string, Dictionary<string, object>>()
{
["WNodeScramblingResetZone_Unlock"] =
{
["updater"] ="pinco",
["rdlev"] = 55
},
["WNodeScramblingResetZone_NewPwd"] =
{
["updater"] ="pallo",
["wrlev"] = 75,
["is_online"] = true
}
};
这种语法似乎很好:没有编译错误。但是,当程序启动时,我在输出窗口中看到一些“KeyNotFoundException”错误,并且应用程序不起作用。
顺便说一句,如果我明确声明了嵌套类型实例化,那么一切都运行正常。
var map = new Dictionary<string, Dictionary<string, object>>()
{
["WNodeScramblingResetZone_Unlock"] = new Dictionary<string, object>()
{
["updater"] ="pinco",
["rdlev"] = 55
},
["WNodeScramblingResetZone_NewPwd"] = new Dictionary<string, object>()
{
["updater"] ="pallo",
["wrlev"] = 75,
["is_online"] = true
}
};
这是一个限制,一个错误,还是有一个具体的理由来定义它?
答案 0 :(得分:3)
当你编写这样的代码时:
var map = new Dictionary<string, Dictionary<string, object>>()
{
["WNodeScramblingResetZone_Unlock"] =
{
["updater"] ="pinco"
}
};
它被编译成相当于:
var map = new Dictionary<string, Dictionary<string, object>>()
map["WNodeScramblingResetZone_Unlock"]["updater"] = "pinco";
它不会创建您没有明确指定的任何实例。
这是 可以工作的代码(这就是为什么它被允许)为某些类似字典的类,它为不存在的键返回空集合,但是确实导致KeyNotFoundException
的{{1}}。
另一方面,这段代码:
Dictionary
编译为:
var map = new Dictionary<string, Dictionary<string, object>>()
{
["WNodeScramblingResetZone_Unlock"] = new Dictionary<string, object>()
{
["updater"] ="pinco"
}
};
正如您所看到的,这会使用新实例(而不是之前版本中的getter)调用var map = new Dictionary<string, Dictionary<string, object>>();
var tmp = new Dictionary<string, object>();
tmp["updater"] = "pinco";
map["WNodeScramblingResetZone_Unlock"] = tmp;
setter ,这就是它工作的原因。
答案 1 :(得分:1)
我使用http://tryroslyn.azurewebsites.net/将这个C#代码翻译成VB.NET:
Public Class Program
Public Shared Sub Main()
Dim expr_06 As Dictionary(Of String, Dictionary(Of String, Object)) = New Dictionary(Of String, Dictionary(Of String, Object))()
expr_06("x")("updater") = "pinco"
expr_06("x")("rdlev") = 55
expr_06("y")("updater") = "pallo"
expr_06("y")("wrlev") = 75
expr_06("y")("is_online") = True
End Sub
End Class
它清楚地表明,新的词典不是仅通过密钥访问的。新的[key] = value
语法编译为dictionary[key] = value
,而不是编译为{key, value}
的旧版dictionary.Add(key, value)
。
我认为这是一个功能,编译器不知道您需要什么类型的IDictionary
,因此您必须提供具体的类型。您还可以使用一些动态集合,在第一次访问时自动创建子代码,此代码可以使用。正如您可能看到的那样,编译器让您可以自由地执行您想要的操作而牺牲程序的详细程度。
编辑:我写了一点冗长的blog post about initializers,提供了更深入的解释