C# 隐式类型数组:为什么我们可以';是否显式设置数组大小?

C# 隐式类型数组:为什么我们可以';是否显式设置数组大小?,c#,C#,C#语言规范(7.6.10.4)指出,有三种数组创建表达式: 新的非数组类型[表达式列表]秩说明符sopt数组初始值设定项opt 新的数组类型数组初始值设定项 新的秩说明符数组初始值设定项 第三个用于隐式类型数组: var foo = new[] { 1, 2, 3 }; 问题是:在隐式类型数组的情况下,是否有重要的理由禁止显式设置数组大小 与此语法相比,它看起来像是不对称行为: var foo = new int[3] { 1, 2, 3 }; 更新 稍微澄清一下。我可以看到,显式设置数组

C#语言规范(7.6.10.4)指出,有三种数组创建表达式:

新的非数组类型[表达式列表]秩说明符sopt数组初始值设定项opt
新的数组类型数组初始值设定项
新的秩说明符数组初始值设定项

第三个用于隐式类型数组:

var foo = new[] { 1, 2, 3 };
问题是:在隐式类型数组的情况下,是否有重要的理由禁止显式设置数组大小

与此语法相比,它看起来像是不对称行为:

var foo = new int[3] { 1, 2, 3 };
更新

稍微澄清一下。我可以看到,显式设置数组大小和数组初始值设定项组合的唯一优点是编译时检查初始值设定项长度。如果我声明了三个
int
s的数组,则初始值设定项必须包含三个
int
s


我认为,隐式类型数组也有同样的优势。当然,使用或不使用这一优势是个人的偏好。

我认为这里的一个区别是,这种语法可以被视为首先创建类型化数组,然后填充它:

var foo = new int[3] { 1, 2, 3 };
这类似于我们在一条语句中声明和初始化其他数据类型的方式:

var list = new List<string>{ "a", "b", "c" };
var dict = new Dictionary<string, string>{ {"a", "b"}, {"c", "d"} };
这不是一回事。没有像
[3]
这样的数据类型,因此与其他两个示例不同,这不是首先创建特定对象并填充它的情况。这是一种用于创建隐式类型数组的特殊语法,其中数组及其内容从大括号的内容推断出来,然后创建


我不知道为什么这种语法不应该存在,但我认为这是一个合理的解释,可以解释你所看到的不对称现象。

+1。我必须承认。。我从来没有注意到这一点(每次我都是第一次这样做。)您讨论的是匿名数组初始化。如果我理解你的意思,你是在问匿名数组是否可以定义得更紧一点。我怀疑他们本可以这样设计,但我看不出有什么明显的优势。这就像在沙滩上画一条线。微软的开发人员必须把它画在某个地方。为什么没有?允许这样做有什么意义?@BrianRasmussen:对于显式类型的数组,允许这样做有什么意义?我想,这一点是一样的——如果我已经声明,必须有3个元素,初始值设定项必须包含3个元素。@Dennis,虽然我认为这更像是一个哲学观点,而不是其他任何东西,但这是一个很好的观点+1我想他意识到了这一点。问题似乎是,为什么是这样而不是那样?OP可以定义固定大小的匿名数组。我要说的是,所有的方法都同样合理,只要它们的含义和形式是一致的。@DaveA:没错。就个人而言,如果有初始值设定项,我从不设置数组长度。但是,如果允许显式类型的数组使用它,我看不出有任何理由禁止隐式类型的数组使用它。@Dennis,Microsoft只是这样设计的,如果您同时提到秩和项,编译器在编译时将如何检查?@Anandkumar:它检查显式类型数组的方式相同。我看不出有任何矛盾。:)>这不是一个先创建一个对象然后填充它的例子——我明白你的观点,但我不能同意。类型推断意味着编译器只推断该类型,而不是由程序员显式设置。这并不意味着编译器会发出IL,从而创建未知类型的对象。如果你仔细观察发出的IL,你会看到具体的类型。是的,这都是真的,但我的观点是它们是两种不同类型的语法。通常情况下,涉及推理的语法模式不允许您选择在任何地方插入约束。例如,您可以使用
G(F)
定义一个具体的方法
stringf(stringa){returna;}
并将
F
传递给一个方法G,该方法使用
G(F)
,但您不能这样做:
G(string(stringst)=>return st;)
如果要绝对确保匿名函数体中的
st
和返回值是字符串。我认为这是一个类似的想法。
var foo = new[3] { 1, 2, 3 };