为什么编译器无法推断出对象数组类型?

时间:2014-03-17 21:51:41

标签: c# arrays type-inference

我想知道为什么这是有效的:

object[] array = {"bla bla bla..", 23, true};

但这些不是:

var array = {"bla bla bla..", 23, true };
var array2 = new [] {"bla bla bla..", 23, true };

在第二个例子中,为什么编译器不能根据数组初始值设定项中的值推断出数组类型?这似乎很容易,特别是与泛型类型推断相比。为了定义一个对象数组,为什么我必须明确指定数组类型?

var array = new object[] { "bla bla bla..", 23, true };

3 个答案:

答案 0 :(得分:6)

因为数组中的类型不是特定的object - 它们是3种不同的类型,它们都是对象的子类。

如果使用可在数组中推断的特定类型,编译器将推断该类型。例如,这很好:

var arr = new[] {3, 4, 5}; // Will correctly infer int[]

请注意,这在C#语言规范的8.5.1中明确指出,该规范指出var受到以下限制:

  • local-variable-declaration不能包含多个local-variable-declarators。
  • local-variable-declarator必须包含local-variable-initializer。
  • local-variable-initializer必须是表达式。
  • 初始化表达式必须具有编译时类型。
  • 初始化表达式不能引用声明的变量本身

对于数组,有一个指定的例子:

var y = {1, 2, 3};   // Error, array initializer not permitted

至于new [] {"bla bla bla..", 23, true };示例,这在7.6.10中被调用。在那里,这个例子:

var d = new[] { 1, "one", 2, "two" }; // Error

据说是错误,因为:

  

最后一个表达式导致编译时错误,因为int和string都不能隐式转换为另一个,因此没有最佳的常见类型。在这种情况下,必须使用显式类型的数组创建表达式,例如将类型指定为object []。或者,可以将其中一个元素强制转换为公共基类型,然后将其作为推断元素类型

答案 1 :(得分:2)

我想说这更像是一种安全功能。当然,编译器可以总是推断出最小公分母object

但请考虑后果:在初始化您打算使用特定类型的数组时出错:(此处为int

var array = {1, 2, 3, 4, 5, "6", 7, 8, 9};

通过副本&粘贴错误,您将"6"保留为字符串。您没有抛出编译错误,而是留下了无意的object[],这可能会导致您打算int[]的问题。

这不是Python - 我更喜欢通过节省几个字符进行显式输入。

答案 2 :(得分:1)

根据微软的说法

  

数组元素必须都是相同的类型或隐式转换为相同的类型[...]。最佳类型必须是数组表达式中存在的类型之一。元素不会转换为新类型,如object。

请参阅:Compiler Error CS0826