Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# Can';无法理解为什么无法编译对象初始值设定项中的数组初始值设定项_C#_Clr - Fatal编程技术网

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我试着编辑邮寄地址