gpt4 book ai didi

c# - 为什么我不能将数组初始值设定项与隐式类型变量一起使用?

转载 作者:可可西里 更新时间:2023-11-01 03:12:55 24 4
gpt4 key购买 nike

为什么我不能对隐式类型变量使用数组初始值设定项?

string[] words = { "apple", "strawberry", "grape" };                 // legal
string[] words = new string[]{ "apple", "strawberry", "grape" }; // legal
var words = new []{ "apple", "strawberry", "grape" }; // legal
var words = new string[]{ "apple", "strawberry", "grape" }; // legal

var words = { "apple", "strawberry", "grape", "peach" }; // ILLEGAL

此限制是否有技术原因?为什么它不能像以下那样推断类型:

var number = 10;
var text = "Hello";

编译器清楚地知道我要做什么,只是不允许:

CS0820: Cannot assign array initializer to an implicitly typed local


更新:我使用四种合法的数组声明方法编译了一个程序,它生成了相同的 IL:http://pastebin.com/28JDAFbL

这只会增加我的困惑。并且“它是这样的,因为规范是这样说的”几乎没有帮助。为什么规范是这样的?这里的基本原理是什么?

最佳答案

Why can't I use the array initializer with an implicitly typed variable? Why is the spec like this? What is the rationale here?

做出这个决定时我不在设计团队中,设计说明 (*) 对此主题没有提及。但是,我问了 2005 年做出这个决定时在场的人。

解释是平淡无奇的。设计团队从一开始就对数组初始值设定项语法非常不满意。坦率地说,数组初始值设定项不是表达式并且在语法上只能出现在局部或字段声明中,这实在是太奇怪了。它使解析器复杂化。看起来很奇怪

int[] x = {1};

应该是合法的,但是

M({1});

不是。

数组初始化语法也使编辑时代码分析期间的错误恢复变得复杂。假设你有这样的东西:

class C
{
void M()
{
{
int result = whatever();
...
}
{
int result = somethingElse();
...
}
}
}

然后您开始在编辑器中输入新的声明:

    void M()
{
int[] x =
{
int result = whatever();

现在突然之间,解析器必须以一种不会混淆即将键入“null;”的可怜用户的方式来消除歧义。很明显,您不打算用代码块初始化局部变量,但是解析器完全有权说大括号只能合法在这里作为数组初始化程序的一部分,因此它是意外的“int result”。

所以,长话短说,“经典的”数组初始值设定项有点不当。由于向后兼容的原因,我们无法摆脱它们。但我们也不想通过允许它们出现在更多 地方来鼓励它们的使用。

设计团队想出了在数组初始值设定项前面加上“new[]”的想法,并使that 成为合法的表达式,现在问题就解决了。经典数组初始值设定项的错误特征不会“蔓延”到语言的新领域,并且有一个简洁但可读的语法清楚地表明“您正在此处创建一个新数组”。

这个故事的寓意是:尝试一次就做对,因为语法是永恒的。


(*) 在我的搜索中,我确实发现了一些有趣的事情:该团队最初认为“var”可能不会成为该功能的关键字;显然它在他们身上成长。此外,一种设计要求“var”局部变量不仅是隐式类型的,而且是 init-once 局部变量。显然,我们从未实现过 init-once locals。

关于c# - 为什么我不能将数组初始值设定项与隐式类型变量一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7351453/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com