我想知道为什么这是有效的:
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 };
答案 0 :(得分:6)
因为数组中的类型不是特定的object
- 它们是3种不同的类型,它们都是对象的子类。
如果使用可在数组中推断的特定类型,编译器将推断该类型。例如,这很好:
var arr = new[] {3, 4, 5}; // Will correctly infer int[]
请注意,这在C#语言规范的8.5.1中明确指出,该规范指出var
受到以下限制:
对于数组,有一个指定的例子:
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。