初始化语法不一致

本文关键字:不一致 语法 初始化 | 更新日期: 2023-09-27 18:06:57

在c#中,以下语法是有效的,这是有意义的:

string[] v = {"a","b"};

但是现在考虑这个。假设我们定义

void method(string[] p) {...};

则下列语句无效:

method({"a","b"});

,这与上述不一致。

是否有技术上的原因使这里的方法调用不是有效的语法?也就是说,对语法的解释是否存在歧义?或者是否存在内存管理或持久性方面的问题,使其无法实现?

编辑:Eric Lippert下面的回答很有趣——但它回答了设计的"为什么",我实际上并没有问这个问题(实际上这个问题最初是封闭的,因为它看起来好像我在问他的答案)。

L。B的回答可能确实不是最初的"为什么"不允许这种语法的"原因"(根据Eric L.的评论)。然而,到目前为止,L.B的回答当然是一个正确的技术原因,为什么这种语法不能被允许,这实际上是我要问的问题,所以我选择选择L.B的答案是正确的(尽管老实说这是一个艰难的选择…)。

初始化语法不一致

简短的回答:这是语法的奇怪之处。我一直认为这是一个"疣"。你可以从很多方面来看待这件事,说它很奇怪。奇怪的是,它是少数几种情况之一:

T x = y;

T x; x = y;

是不同的。或者,另一种看待它的方式是,局部变量初始化器是一个上下文,其中可以出现非表达式的内容,这是很奇怪的。

或者另一种看待它的方式是它真的很奇怪,这是唯一的情况下,一个新的数组被创建,但"new"没有出现在任何地方。

或者另一种看待它的方式是,数组可以这样初始化,但其他集合结构却不能,这真的很奇怪。这使得数组看起来特别特别和重要,尽管它们通常不是完成这项工作的正确工具。

我想如果我们必须重新做一次,可能初始化器会要求new[]在它们的左边。

是否有技术上的原因使这里的方法调用不是有效的语法?也就是说,对语法的解释是否存在歧义?

没有。不要过分解读这件怪事。我的建议是完全避免这种语法;坚持使用适当的集合初始化式或数组初始化式。它们的语法几乎完全相同,但在表达式合法的地方都是合法的。

关于另一个答案,l.b.:虽然这个答案似乎指出这里有一个设计问题,但它忽略了历史的观点。被批评的特性是在c# 1.0中创建的,比泛型类型推断(c# 2.0)或其他带括号的集合初始化器(c# 3.0)早了几年。因此,不能以与几年后出现的功能发生冲突为基础,为1.0功能的设计选择辩护。c#设计团队试图向前看,但他们并没有那么向前看!

假设您有另一个方法

void method(KeyValuePair<string,string> p) {}

将其称为method({"a","b"});会导致歧义…

记住{"a","b"}也可以是KeyValuePair<>和这里一样

var dict = new Dictionary<string, string>() { { "a", "b" } };