【问题标题】:Why does C# allow trailing comma in collection initializers but not in params?为什么 C# 允许在集合初始值设定项中使用尾随逗号,但不允许在参数中使用逗号?
【发布时间】:2015-01-08 00:14:21
【问题描述】:

有效语法:

var test = new List<string>
{
   "a",
   "b",
   "c",//Valid trailing comma
};

语法无效:

private void Test(params string[] args)
{
}

Test(
   "a",
   "b",
   "c",//Invalid trailing comma
);

这是语法不一致的问题还是经过计算的决定?

【问题讨论】:

  • 在第二个示例中,编译器使用逗号分隔方法参数,而不是集合项。 params 单独处理。在方法参数上,您永远不能留下逗号。
  • 编译器不是人,它不知道也不关心你想将集合传递给方法。它只是“看到”语法无效。前一种语法是有效的,因为语言规范允许初始化集合。
  • 这个问题被错误地关闭为重复。 The linked question 回答“为什么我们允许在集合初始化器上使用尾随逗号”,而这是在问“为什么我们不允许在 params 方法参数中使用尾随逗号”。也就是说,答案将是相似的 - 但问题不是。
  • 不同之处在于,无论有没有params,方法调用看起来都一样。从技术上讲,这可能是可能的,但后来添加了 params 和初始化程序。
  • 这就是为什么在第一种情况下允许使用逗号:stackoverflow.com/questions/2147333/… 我认为不同之处在于,在初始化列表时,您列出的是相同类型的元素,但是在调用函数时,您可以那里有任何东西,所以语法要严格得多。

标签: c# syntax comma


【解决方案1】:

所以我会尝试一下,即使我永远不会知道“真正”的原因,因为我不在编译器团队 - 而且出现的可能性值得怀疑。

尾随逗号通常在少数情况下很有用,即合并和代码生成。在集合或属性初始化器和枚举等内容的上下文中,留下一个尾随逗号是无害的(编译器可以安全地推断“列表结尾”,因为它还有一个可以挂钩的右块括号。

方法参数非常明确 - 编译器需要在这方面进行大量控制,以便在人们编码和其他辅助功能时提供良好的反馈。在方法参数上留下一个尾随逗号不会像上面那样添加任何值,我开始对如何处理“不完整”代码造成混淆(用户是故意把它留在那里还是他们只是要输入下一个参数?)。

您认为params 属于概念 差距是正确的,因为您将它们视为一个数组,并且您可以将它们指定为逗号分隔(在集合初始化程序之前支持)。那么为什么它们在风格上与集合初始化器不同呢?

params 位的语言规范没有明确指定尾随逗号支持,但它确实用于与其他语言(我认为是 C++)奇偶校验的集合初始化程序,这增加了开发人员从其他地方迁移到 C# 的熟悉度。

我的假设:它不在规范中的事实导致 YAGNI 应用,从那时起,该功能的价值主张就是不实施它的明智之举。

【讨论】:

  • “用户是故意把它留在那里还是他们只是要输入下一个参数?”推理同样适用于枚举和初始化列表。此外,方法调用也存在于生成的代码中,并且也在被合并:)
  • 确实如此,但推理不太重要,因为编译器不会尝试连接未知的枚举值。我认为它属于最低价值和开发成本的范畴。肯定有它的论据,我不争论任何一种情况。我只是想弄清楚为什么事情会这样。
  • 您评论中关于“未知值”的部分似乎在这一点上恰到好处。您的答案中的概念差距也 - 它们似乎最相关,其他部分几乎是噪音;)尽管总体上对这个难题进行了很好的尝试。
  • @BartoszKP 谢谢 :-) 不过我同意你的观点。似乎它可以被支持并属于与 enums 等人相同的论点类别。谁知道,既然 Roslyn 正在实现更快的迭代和更低的开发成本,我们可能会看到这些有争议的矛盾开始得到解决。
【解决方案2】:

如果您查看词汇语法here

C.2.9 数组

array-initializer:
{   variable-initializer-listopt   }

{   variable-initializer-list   ,   }// This comma is causing this

variable-initializer-list:
variable-initializer
variable-initializer-list   ,   variable-initializer

调用函数是这样的 ....MethodName(formal-parameter-listopt);

 formal-parameter-list:
 fixed-parameters
fixed-parameters   ,   parameter-array
parameter-array
fixed-parameters:
fixed-parameter
fixed-parameters   ,   fixed-parameter
fixed-parameter:
attributesopt   parameter-modifieropt   type   identifier
parameter-modifier:
ref
out
parameter-array:
attributesopt   params   array-type   identifier

后面没有逗号,因为语言是这样写的,我不知道原因,但亚当知道

【讨论】:

    猜你喜欢
    • 2012-07-20
    • 2011-10-25
    • 2015-05-19
    • 2016-04-05
    相关资源
    最近更新 更多