C# Can';无法理解为什么无法编译对象初始值设定项中的数组初始值设定项
我看到了,有一个更新,但我仍然无法理解C# Can';无法理解为什么无法编译对象初始值设定项中的数组初始值设定项,c#,clr,C#,Clr,我看到了,有一个更新,但我仍然无法理解 var arr=newint[]{1,2,3}使用stelem生成IL代码。 但是int[]arr={1,2,3}使用RuntimeHelpers.InitializeArray生成IL代码。我认为它使用的是Array.Addextension方法,这个方法就是在那个答案中提到的 但在对象初始值设定项中,所有数组初始值设定项都会生成第二个代码。 例如, new A() { arr = new int[] { 1, 2, 3 } } 数组arr是
var arr=newint[]{1,2,3}
使用stelem
生成IL代码。
但是int[]arr={1,2,3}
使用RuntimeHelpers.InitializeArray
生成IL代码。我认为它使用的是Array.Add
extension方法,这个方法就是在那个答案中提到的
但在对象初始值设定项中,所有数组初始值设定项都会生成第二个代码。
例如,
new A() {
arr = new int[] { 1, 2, 3 }
}
数组arr
是使用RuntimeHelpers创建的。也可以初始化数组。那么,这不意味着下一个代码中没有任何问题吗
new A() {
arr = { 1, 2, 3 } // Compiler error!
}
与旧版本的c#编译器不同,它会使编译器错误地说system.array不包含Add
的定义。发生了什么事
编辑
我认为没有new[]
的语法会产生差异,但实际上有三个以上的元素会产生不同的IL代码 第二个语法({arr={…}}
)是value.arr.Add(.)
序列的语法糖-大概value.arr
未在构造函数中初始化,因此是NRE
假设A
为:
class A {
public int[] arr {get;set}
}
然后
与
var x = new A(); // note x.arr is default null here
x.arr.Add(1); // NRE is arr is list, can't compile for int[]
x.arr.Add(2);
x.arr.Add(3);
修正:使用列表,没有合理的方法将元素添加到数组中。
如果使用的其他类型没有.Add
-实现对该代码可见的扩展方法
使用new
的版本为什么有效:
var x = new A() {
arr = new int[] { 1, 2, 3 }
};
相当于
请注意,在数组初始值设定项中,可以使用两个语法,但不能在数组字段的初始值设定项()中使用
而newa{arr={10,20,30}}
与newa{arr=newint[3]{10,20,30}
*当必须观察到更改时,满足规则确实有点复杂-请参见Eric Lippert的第二个语法({arr={…}}
)是值序列的语法糖。arr.Add(.)
-可能值。arr
未在构造函数中初始化,因此是NRE
假设A
为:
class A {
public int[] arr {get;set}
}
然后
与
var x = new A(); // note x.arr is default null here
x.arr.Add(1); // NRE is arr is list, can't compile for int[]
x.arr.Add(2);
x.arr.Add(3);
修正:使用列表,没有合理的方法将元素添加到数组中。
如果使用的其他类型没有.Add
-实现对该代码可见的扩展方法
使用new
的版本为什么有效:
var x = new A() {
arr = new int[] { 1, 2, 3 }
};
相当于
请注意,在数组初始值设定项中,可以使用两个语法,但不能在数组字段的初始值设定项()中使用
而newa{arr={10,20,30}}
与newa{arr=newint[3]{10,20,30}
*当必须观察到更改时,满足规则确实有点复杂-请参见Eric Lippert在表达式上下文中的,这些是合法的数组值:
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }
在本地或成员变量初始值设定项上下文中,这是合法的数组初始值设定项:
int[] x = { 10, 20, 30 };
new A() {
arr = { 10, 20, 30 }
}
这是一个合法的集合初始值设定项:
int[] x = { 10, 20, 30 };
new A() {
arr = { 10, 20, 30 }
}
但在成员或集合初始值设定项上下文中,这不是合法的数组属性初始值设定项:
int[] x = { 10, 20, 30 };
new A() {
arr = { 10, 20, 30 }
}
(请注意,我在这里总结并评论了数组的规则)
我的理解是,问题是“为什么不?”
答案是“没有充分的理由”。这只是C#语法以及对象和集合初始值设定项规则的一个奇怪之处
我曾多次考虑解决这个奇怪的问题,但总有更好的办法来利用我的时间;这是一个基本上对任何人都没有好处的修复方法,因为解决方法非常简单
我猜想没有什么能阻止C#团队设计、指定、实现、测试和发布该功能,除了还有大约一百万个其他功能可以更好地利用他们的时间
如果你对它有强烈的感觉,那么,编译器是开源的;您可以自由地提出该功能并为其辩护。或者,就此而言,实现它并提交一个请求。(在您提出该功能之后。)
在实现您想要的功能之前,您只需使用上面列出的三种“表达式”形式之一。这样做并不麻烦。在表达式上下文中,这些是合法的数组值:
new int[3] { 10, 20, 30 }
new int[] { 10, 20, 30 }
new[] { 10, 20, 30 }
在本地或成员变量初始值设定项上下文中,这是合法的数组初始值设定项:
int[] x = { 10, 20, 30 };
new A() {
arr = { 10, 20, 30 }
}
这是一个合法的集合初始值设定项:
int[] x = { 10, 20, 30 };
new A() {
arr = { 10, 20, 30 }
}
但在成员或集合初始值设定项上下文中,这不是合法的数组属性初始值设定项:
int[] x = { 10, 20, 30 };
new A() {
arr = { 10, 20, 30 }
}
(请注意,我在这里总结并评论了数组的规则)
我的理解是,问题是“为什么不?”
答案是“没有充分的理由”。这只是C#语法以及对象和集合初始值设定项规则的一个奇怪之处
我曾多次考虑解决这个奇怪的问题,但总有更好的办法来利用我的时间;这是一个基本上对任何人都没有好处的修复方法,因为解决方法非常简单
我猜想没有什么能阻止C#团队设计、指定、实现、测试和发布该功能,除了还有大约一百万个其他功能可以更好地利用他们的时间
如果你对它有强烈的感觉,那么,编译器是开源的;您可以自由地提出该功能并为其辩护。或者,就此而言,实现它并提交一个请求。(在您提出该功能之后。)
在实现您想要的功能之前,您只需使用上面列出的三种“表达式”形式之一。这样做并不麻烦。但是newa(){arr=new[]{1,2,3}}
有效。有什么区别?@phillyai:该值正在初始化并填充为数组。如果没有新的[],它将使用arr的当前状态,并将sugar转换为一系列.Add扩展方法调用。@JonathonChase,但请检查此项。“结果也是一样的。”phillyai我试着编辑邮寄地址