Dictionary 初始化中出现 KeyNotFoundException 的原因
Reason for KeyNotFoundException in Dictionary initialization
如下代码
new Dictionary<string, List<int>> {
["a"] = {1},
};
抛出 运行 次 KeyNotFoundException
,尽管 {1} 是一个格式完美的数组(即 int[] a = {1,2,3,4}
是有效代码)。将 Dictionary
的 TValue
更改为 int[]
,会引发编译时 CS1061
,但这不会(注意添加的 new[]
数组分配):
new Dictionary<string, IEnumerable<int>> {
["a"] = new[]{1},
};
为什么会这样?
您的第一段代码使用了集合初始值设定项,它不使用逻辑赋值,而是打算在 现有 集合上调用 Add
。换句话说,这个:
var x = new Dictionary<string, List<int>> {
["a"] = {1},
};
相当于:
var tmp = new Dictionary<string, List<int>>();
var list = tmp["a"];
list.Add(1);
var x = tmp;
希望扩展的第二行会抛出异常的原因显而易见。
你的部分推理错误是:
albeit that {1} is a perfectly well-formed array
不,不是。语法 {1}
在不同的上下文中有不同的含义。在本例中,它是一个集合初始化器。在声明中:
int[] a = { 1, 2, 3, 4 };
这是一个数组初始化器。该语法 only 在数组声明中创建一个新数组,或者作为数组创建表达式的一部分,例如new[] { 1, 2, 3, 4 }
.
如下代码
new Dictionary<string, List<int>> {
["a"] = {1},
};
抛出 运行 次 KeyNotFoundException
,尽管 {1} 是一个格式完美的数组(即 int[] a = {1,2,3,4}
是有效代码)。将 Dictionary
的 TValue
更改为 int[]
,会引发编译时 CS1061
,但这不会(注意添加的 new[]
数组分配):
new Dictionary<string, IEnumerable<int>> {
["a"] = new[]{1},
};
为什么会这样?
您的第一段代码使用了集合初始值设定项,它不使用逻辑赋值,而是打算在 现有 集合上调用 Add
。换句话说,这个:
var x = new Dictionary<string, List<int>> {
["a"] = {1},
};
相当于:
var tmp = new Dictionary<string, List<int>>();
var list = tmp["a"];
list.Add(1);
var x = tmp;
希望扩展的第二行会抛出异常的原因显而易见。
你的部分推理错误是:
albeit that {1} is a perfectly well-formed array
不,不是。语法 {1}
在不同的上下文中有不同的含义。在本例中,它是一个集合初始化器。在声明中:
int[] a = { 1, 2, 3, 4 };
这是一个数组初始化器。该语法 only 在数组声明中创建一个新数组,或者作为数组创建表达式的一部分,例如new[] { 1, 2, 3, 4 }
.