初始化语法不一致

时间:2016-09-14 19:56:15

标签: c#

在C#中,以下是有效的语法,这是有道理的:

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

但现在考虑一下。假设我们定义

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

然后以下内容无效:

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

与上述内容不符。

是否有技术原因阻止此处的方法调用是有效的语法?也就是说,语法的解释是否存在歧义?或者是否存在内存管理或持久性问题导致无法实现?

编辑: Eric Lippert在下面的回答很有意思 - 但是它回答了设计的“原因”,我实际上并没有问过(事实上这个问题最初是因为看起来好像我在问他的答案)。

L.B的答案可能确实不是原始的“理由”这种语法是不允许的(根据Eric L.评论)。然而,LB的回答,截至目前,肯定是一个正确的技术原因,为什么不允许这样的语法,这实际上是我问的问题,所以我选择LB的答案是正确的(虽然老实说它是一个艰难的选择......)。

2 个答案:

答案 0 :(得分:7)

简短的回答:语法很奇怪。我一直认为这是一个“疣”。你可以通过多种方式看待这件事并说它很奇怪。奇怪的是,这是少数情况之一:

T x = y;

T x; x = y;

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

或者另一种看待它的方式是,这是创建新数组但“新”不会出现在任何地方的唯一情况,这真的很奇怪。

或者另一种看待它的方法是,可以像这样初始化数组真的很奇怪,但是没有其他的集合结构可以。它使得数组看起来特别重要,即使它们通常不适合这项工作。

我认为如果我们不得不重新做一遍,可能初始化者需要在他们的左边new[]

  

是否有技术原因阻止此处的方法调用是有效的语法?也就是说,语法的解释是否存在歧义?

不是真的。不要过多地读到这种奇怪的东西。我的建议是完全避免语法;坚持使用适当的集合初始化器或数组初始化器。它们具有几乎完全相同的语法,但在表达式合法的任何地方都是合法的。

关于L.B的另一个答案:虽然这个答案确实可以指出这里存在设计问题,但它忽略了历史的观点。被批评的特征是在C#1.0中创建的,这是在添加泛型类型推断(C#2.0)或其他支撑集合初始化器(C#3.0)之前的几年。因此,基于与多年后出现的功能的某些冲突,人们无法为1.0功能的设计选择辩护。 C#设计团队试图向前看,但他们并非 向前看!

答案 1 :(得分:3)

假设您有另一种方法

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

将其称为method({"a","b"});会导致含糊不清..

请记住,{"a","b"}也可能是 KeyValuePair&lt;&gt; ,因为

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