为什么我不能声明一个没有初始化器的隐式类型数组?

10

如果我在声明数组 num 时没有初始化它,为什么我要在 new 后面写上 int?例如:

int[] num = new int[5];

对于另一个数组,num1,我只是先声明了它,然后给它赋值,而且我没有像为数组 num 做的那样在 new 后面输入 int

int[] num1 = new [] {1, 2, 3, 4};
为什么这个快捷方式在我的第一个示例中无法使用?

5
如果你不喜欢“new”,你可以使用简写的方式int[] nums = { 1, 2, 3, 4 },这样可以实现同样的功能。 - Scott
6
@WillemVanOnsem 这与继承无关。 - Blorgbeard
7
那跟构建数组的语法有什么关系? - Servy
除了答案外,还可以参考:https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/arrays#array-initializers - Fildor
1
@Slai,问题明确展示了在提供值时隐式定义数组的C#代码。说你可以在VB中做同样的事情并没有展示两者之间的差异,而是指出了一个相似之处 - Servy
显示剩余5条评论
5个回答

10

在某些情况下(你的示例满足这些条件),如果你提供了数组的值,数组的类型可以被推断出来。由于这些值都是整数,编译器能够推断出你想要一个整数数组。如果你没有提供任何值(或者值无法隐式转换为其中一个值的类型),编译器就无法推断数组应该是什么类型,因此需要明确指定。


9
声明一个有值的数组的完整语法是new int[] {1, 2, 3, 4};
你的new [] {1, 2, 3, 4};行是一种简写语法。它是一个"隐式类型"数组。由于所有的值都是int,所以数组会自动声明为int[]
你不能写int[] x = new [5];的原因很简单,这个功能还没有被C#设计者实现。

3

因为您似乎期望编译器推断数组类型的方式与赋值操作符左侧的类型有关:

int[] num = new[5];

您的思路如下:

  1. num是一个int数组。
  2. new[5]是一个由某种类型组成的数组。
  3. 由于num 的类型为int,所以这个类型必须也是int

但这并不是编译器的工作方式。编译器必须明确地确定赋值表达式右侧的类型,并一旦确定,它将检查左侧任何内容是否有效。

在C#中允许的语法中,编译器总是具备足够的信息来确定赋值操作符右侧的类型(如果存在)。您提出的语法无法提供这些信息。


这不是编译器的工作方式。编译器必须明确地确定赋值表达式右侧的类型,一旦确定,它将检查左侧任何内容的赋值是否有效。这是简短而甜美的答案 :) 是否有任何例外情况? - rahulaga-msft
还有为什么 var array = new [] {1, "something"}; 不能隐式转换为 object[] - rahulaga-msft

2
在第一个场景中,您声明了一个空数组,因此需要确定它的类型。
int[] num = new int[5]; // New empty array of integers with 5 slots.

然而,在你的第二个例子中,数组的类型是根据你分配给数组槽位的值来隐含确定的。

int[] num1 = new [] {1, 2, 3, 4}; // New array of integers with 4 slots, already assigned.

上述代码之所以可行,是因为数组中的每个元素都是相同类型的。 如果您执行以下操作,将会出现编译错误,因为无法推断类型,因为元素是不同的类型。
var array = new [] {1, "something"}; // This won't compile.

但是,如果您将其中一个元素声明为公共基础类型,则它将以该基础类型存储所有元素。

var array = new [] {(object)1, "something", DateTime.Now}; // This is an array of objects.

0
为什么我在声明具有默认值的数组num时,必须在new后面写int?
其实不用。通常情况下编译器可以推断出你创建的数组类型,就像你这种情况一样。
所以这是一个完全正确的声明:
var num1 = new[] { 1, 2, 3, 4 };

你看,这里没有int,但如果你将鼠标悬停在var上,它会告诉你数组是一个int[]

当你混合类型时,问题就变得更加困难了:

var num1 = new [] { "1", 1 };

那么编译器就不知道,强制你指定一个类型。


为什么 var num1 = new [] { "1", 1 }; 不能隐式转换为 object[] - rahulaga-msft
因为1不是一个对象。@rahul - Patrick Hofman
1
谢谢!但是 var num1 = new[] { new object(), 1 }; 隐式转换为 object[],我是说必须有一些规则来控制这种转换。 - rahulaga-msft

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