对同一个变量多次使用数组初始值设定项“{}”不会编译

时间:2010-08-04 14:41:59

标签: c# arrays initialization

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

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

我收到编译错误,如:

Error 1 Invalid expression term '{'
Error 2 ; expected
Error 3 Invalid expression term ','

另一方面,如果我尝试

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

编译好。根据{{​​3}},

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

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

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

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

7 个答案:

答案 0 :(得分:10)

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

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)部分时才允许使用简写符号。

答案 1 :(得分:5)

C#spec 12.6数组初始值设定项

  

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

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

是声明,但

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

不是。

答案 2 :(得分:2)

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

然而,这很接近:

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

答案 3 :(得分:2)

您指的编译器错误是由无效语法引起的。

// 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"};

答案 4 :(得分:1)

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

  

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

答案 5 :(得分:1)

作为变量声明的一部分使用的数组初始化器基本上是特殊的。 (我现在无法查找规范引用,但我可以在以后这样做。)在变量声明之外,编译器并没有真正注意到有一个赋值的事实 - 右边的表达式一方必须站在自己的两只脚上。 1

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

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

这将从其中的元素推断数组的类型(在编译时)...并且假设它与目标变量兼容,则赋值将起作用。此语法在更一般的上下文中工作 - 您可以使用它将数组作为方法参数传递,例如。

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


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

答案 6 :(得分:0)

在初始化期间,您将明确声明数组的类型,这使得此简写清晰且明确。然而,稍后在代码中,一点点歧义开始蔓延。例如,理论上,你可以尝试建立一个对象数组。当然,你可能希望它是一个字符串数组,但为了避免逻辑错误,编译器不想假设这样的东西,除非你非常清楚你想要的是什么做。

相关问题