我回过头来回答“为什么不”的问题,因为首先,答案几乎永远不会令人满意-您已经得到了答案:“功能不是您想要的方式,因为规范没有说您想要说的话” ,我想这不是一个特别令人满意的答案。其次,设计团队不必证明为什么世界不是您想要的样子。功能不是免费存在的,而是根据语言设计的;相反,必须先对功能进行论证,然后再进行设计。
因此,让我们尝试使您的“为什么不”问题更加清晰。现有功能是“可以在(a)初始化中的等号的右侧或(b)数组类型的对象构造的右侧使用数组初始化器”。建议的功能是:“数组初始化器也可以用作表达式”。问题是“埃里克会对提议的功能提出什么批评?”
我要提出的第一个批评是,不清楚表达的类型是什么。在变量初始化器中,您具有变量的类型,在对象创建表达式中,您具有对象的类型;从这两个我们可以推断出构造数组的类型。没有任何提示,我们应该推断出哪种类型?
在C#1.0中,添加了此功能后,使用该语言进行了零类型推断。C#早期的设计原则是“毫无意外”,并且编译器不是“太聪明”。如果开发人员希望表达式具有特定类型,则该类型在表达式中应以某种方式显而易见。当你说
new double[] { 1, 2, 3.4 }
很明显是什么类型的。相似地
new Animal[] { cat, dog, null }
建议的功能违反了该原则。表达式必须具有类型,但绝不能清除参数的类型
M({cat, dog, null})
此外:假设我们有两个重载M,其中一个重载采用的数组,Animal而一个重载则采用的数组IPet。哪个过载M?其中一项转换比另一项转换好吗?元素的类型为Cat和Dog; 推论甚至没有出现在那里的类型是否有意义?这些都是设计团队必须考虑的问题,而这些问题绝不是显而易见的答案。拟议中的功能可以在很短的时间内将我们带入深水区。
现在,C#3.0解决了这个问题,因为C#3.0添加了许多功能,在这些功能中,编译器代表开发人员推断类型。早期有关“没有意外”和“简单规则”的原则与使LINQ工作所需的其他设计原则相冲突。您应该在C#3.0中添加您建议的功能吗?
可能是这样。实际上在C#3.0中添加的功能是:
new[] { x, y, z }
使用算法推断数组的类型:获取具有类型的元素的表达式,确定这些类型中的哪一个是所有其他表达式可转换为的唯一的最通用类型,如果存在这种类型,则选择该类型。否则会产生错误,
可以进一步放松该功能以使其成为new[]可选功能。尚未完成。
现在,如果您在C#3.0的时间范围内要求我批评所建议的功能,我会指出(1)C#3.0编译器已经很可能会拖延整个发行版的时间表,因此,我们不再添加任何其他内容设计,实现和测试的负担,这是一项完全不必要的功能,可为用户节省六次按键操作;(2)C#3.0还添加了集合初始化程序:
new List<int>() { 10, 20, 30 }
为什么要{10, 20, 30}自动成为数组?为什么不应该是List<int>?还是其他多种类型中的任何一种?为什么偏向数组?请记住,一旦我们选择为数组提供语法,我们将永远受其困扰。可能再也没有其他东西了,因此建议的功能不仅不必要,而且还可以防止将来似乎合理的功能。
总结:提议的功能直接违反了C#1.0的某些设计原则。它给C#3.0增添了不必要的负担。自C#3.0以来,在该语言的所有版本中,与许多其他更有价值的功能相比,建议的功能都没有很好的理由建议花时间,精力和金钱在它上面。
因此,没有这样的功能。