为什么我不能在声明数组之外使用数组初始化语法?

12

我可以使用整数来完成这个任务:

int a;
a = 5;

但是我无法使用整数数组来完成这个操作:

int[] a;
a = { 1, 2, 3, 4, 5 };

为什么不呢?

澄清一下,我不是在寻找正确的语法(我可以查找);我知道这个是有效的:

int[] a = { 1, 2, 3, 4, 5 };

这将相当于:

int a = 5;
我想要理解的是,为什么这段代码在数组上会出错?为什么它无法被识别为有效的代码?

3
可以实现这一点。你只需要在这里提出你的想法:https://visualstudio.uservoice.com/forums/121579-visual-studio-2015 根据投票数以及开发人员需要付出的工作量和时间,可能会被接受或不被接受。 - M.kazem Akhgary
4个回答

16
这个差异的原因是微软的开发人员决定在同一语句中声明和初始化数组时简化语法,但没有添加必要的语法以允许您稍后将新数组分配给它。
这就是为什么这个代码可以工作的原因:
int[] a = { 1, 2, 3, 4, 5 };

但这个不行:
int[] a;
a = { 1, 2, 3, 4, 5 };

他们是否可以添加语法来允许这样做?当然,但他们没有这样做。很可能他们觉得这种用例很少被使用,不值得优先考虑其他功能。所有新功能都从负100分开始,这可能在优先级列表上的排名不够高。
请注意,{1, 2, 3, 4, 5}本身没有意义;它只能出现在两个地方:
  • As part of an array variable declaration:

      int[] a = { 1, 2, 3, 4, 5 };
    
  • As part of an array creation expression:

      new int[] { 1, 2, 3, 4, 5 }
    

相反,数字5在C#中无论出现在哪里都有意义,这就是为什么下面的代码有效:

int a;
a = 5;

这只是C#设计者决定支持的特殊语法,没有其他含义。
此语法在C#规范的12.6 数组初始化器章节中有详细说明。

我可以很容易地看出为什么它只在那个特定的实例中起作用,因为在其他任何地方,它可能会令人困惑。只有当您明确输入变量并在那里声明时,才能完全清楚正在发生什么。 - krillgar
不允许这种语法的原因是不清楚 int[] arr; for (int i=0; i < 10; i++) { arr = {1,2,3,4,5}; foo(arr); } 是否有意每次循环都创建一个新数组,还是打算创建一个在每个循环迭代中都使用的数组。如果代码执行 arr = new int[] {1,2,3,4,5}; 那么很明显每次循环都打算创建一个新对象;任何用于仅创建一次数组的合法语法都需要将其创建从循环中提取出来。 - supercat

1
你的数组示例无法正常工作是因为值类型和引用类型之间的差异。一个int是一个值类型。它是内存中的单个位置,其值可以更改。
你的整数数组是一个引用类型。它不等同于内存中的常量字节数。因此,它是指向存储该数据的字节的指针。
在这第一行中,你将null赋给了a
int[] a;

在下一行,如果您想更改数组的值,您需要将其分配给一个新数组。
a = new[] {1, 2, 3, 4, 5};

那就是为什么在强类型声明时,需要在数组中的值列表前加上new[]
int[] a = {1, 2, 3, 4, 5}; // This will work.
var a = {1, 2, 3, 4, 5}; // This will not.

然而,正如其他答案所述,如果您在一行中声明它,则不需要使用new[]。如果您分开声明和初始化,则需要使用new[]

3
这只是在一行声明和初始化变量时的语法糖,不是不使用 new 就不能创建新数组。你可以用这种方式 int[] a = {1, 2, 3, 4, 5}; 来实现所有操作,而且这并不意味着你没有创建新数组。你不能只用两行来完成它,原因很明显,编译器不支持这样做。 - M.kazem Akhgary
如果这么明显,那为什么编译器不喜欢它呢?我已经更新了我的答案,非常清楚地说明了何时以及为什么需要每个东西,以及何时某些东西不起作用。 - krillgar
我想不出任何与此语法冲突的内容。也许还有其他原因,但都与语法有关,没有其他的原因。 - M.kazem Akhgary

-1

{} 语法可用于数组初始化,在声明后不应使用。


-2

要初始化一个数组,你应该尝试这样做:

int[] a = { 1, 2, 3, 4, 5 };

初始化一维数组的其他方法:

int[] a = new int[] { 1, 2, 3, 4, 5 };
int[] a = new int[5] { 1, 2, 3, 4, 5 };

看看这个:不同种类数组的初始化方法


这并没有回答OP提出的问题;他们问的是为什么它不起作用,而不是如何做到。 - TylerH

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接