C# 使用数组初始值设定项';{}';同一变量多次不';不编译

C# 使用数组初始值设定项';{}';同一变量多次不';不编译,c#,arrays,initialization,C#,Arrays,Initialization,我正在尝试用C#编译以下代码: 我得到的编译错误如下: Error 1 Invalid expression term '{' Error 2 ; expected Error 3 Invalid expression term ',' 另一方面,如果我尝试 String[] words = { "Hello", "Worlds" }; words = new String[] {"Foo", "Bar"}; 它编译得很好。根据, 它只是等效数组创建表达式的简写: int[] a = new

我正在尝试用C#编译以下代码:

我得到的编译错误如下:

Error 1 Invalid expression term '{'
Error 2 ; expected
Error 3 Invalid expression term ','
另一方面,如果我尝试

String[] words = { "Hello", "Worlds" };
words = new String[] {"Foo", "Bar"};
它编译得很好。根据,

它只是等效数组创建表达式的简写:

int[] a = new int[] {0, 2, 4, 6, 8};

为什么第一个代码示例不编译?

正确,短初始值设定项语法只允许在声明中使用。这不是正常的说法

String[] words = new string[]{ "Hello", "Worlds" }; // full form
String[] words = { "Hello", "Worlds" };  // short hand, special rule
words = {"Foo", "Bar"};                  // not allowed
words = new String[] {"Foo", "Bar"};     // allowed, full form again

仅当它用作声明的(rhs)部分时,才允许使用简写符号

根据您链接到的文档,数组初始值设定项仅在字段或变量声明中有效-对于变量赋值,您必须事先指定
new[]

在数组创建表达式(一般情况下)中,数组类型紧跟在初始值设定项之前。在字段或变量声明中,数组类型是要声明的字段或变量的类型


根据相同的MSDN页面,此语法特定于数组变量初始化;它不是通用数组语法

然而,这很接近:

String[] words = { "Hello", "Worlds" };
// words = {"Foo", "Bar"};
words = new[] {"Foo", "Bar"};

您引用的编译器错误是由invaild语法引起的

// variable declaration so constructor may be assumed
String[] words = { "Hello", "Worlds" }; 

// attempted variable assignment using invalid syntax
words = {"Foo", "Bar"}; 

// explicit constructor
words = new String[] {"Foo", "Bar"};

// as a note this would also work.  Here the type of the array is assumed.
words = new [] {"Foo", "Bar"};
C#规范12.6数组初始值设定项

在字段或变量声明中,数组类型是要声明的字段或变量的类型。在字段或变量声明中使用数组初始值设定项时,例如: int[]a={0,2,4,6,8}; 它只是等效数组创建表达式的简写: int[]a=新的int[]{0,2,4,6,8}

这是一项声明,但

words = {"Foo", "Bar"};

事实并非如此

用作变量声明一部分的数组初始值设定项基本上是特殊的。(我现在无法查找spec引用,但我可以稍后再查找。)在变量声明之外,编译器实际上没有太多注意到有赋值的事实-右侧的表达式必须自己站立,就像它一样。1

在C#3中,您可以使用稍微缩写的形式:

words = new[] {"Foo", "Bar"};
这将从数组中的元素推断数组的类型(在编译时)。。。假设它与目标变量兼容,赋值就可以了。这种语法在更一般的上下文中工作——例如,您可以使用它作为方法参数传递数组

但是,在变量声明之外,没有办法使用“完全缩写”形式



1不可否认,有些表达式没有类型,例如lambda表达式。

在初始化过程中,您显式声明了数组的类型,这使得这个简写清晰明了。然而,在代码的后面,有一点模棱两可的地方开始出现。例如,从理论上讲,您可以尝试设置一个对象数组。当然,您可能希望它是一个字符串数组,但是为了避免逻辑错误,编译器不希望假设这样的情况,除非非常清楚您要做什么

String[] words = { "Hello", "Worlds" };
words = {"Foo", "Bar"};
words = new[] {"Foo", "Bar"};