Почему С# допускает конечную запятую в инициализаторах коллекции, но не в параметрах?

Действительный синтаксис:

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

Недопустимый синтаксис:

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

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

Это вопрос несогласованности синтаксиса или расчетного решения?

Ответ 1

Итак, я возьму на себя удар, хотя я никогда не узнаю "истинную" причину, так как меня не было в команде компилятора, и вероятность того, что один из них окажется сомнительным.

Конечные запятые обычно полезны в нескольких сценариях, а именно в слиянии и генерации кода. В контексте таких вещей, как сбор или инициализаторы свойств и перечисления, оставляя конечную запятую безвредным (компилятор может смело заключить "конец списка", поскольку есть также скобка закрывающего блока, к которой он может подключиться.

Параметры метода довольно ясны - компилятору требуется много контроля в этой области, чтобы он мог обеспечить хорошую обратную связь, когда люди кодируют и используют другие вспомогательные функции. Если оставить трейлинг-запятую на аргументах метода, это не добавит значения, как указано выше, и мое начало путаницы в том, как обрабатывать "неполный" код (пользователь оставлял его там намеренно или они просто собираются ввести следующий аргумент?).

Вы правы, что params попадают в концептуальный пробел в том, что вы видите их как массив, и вы можете указать их как разделенные запятой (которые были поддерживаются до инициализации коллекции). Итак, почему они уходят в стиле от инициализаторов коллекции?

Спецификация языка для бита params явно не указывает конечную поддержку запятой, хотя для инициализаторов коллекции для контроля четности по отношению к другим языкам (С++, я думаю), что увеличивает знакомство с разработчиками, мигрирующими на С# из других источников.

Мое предположение: тот факт, что он не был в spec, вызывает YAGNI, чтобы применить, и с этого момента пересылает ценное предложение для особенность - не проблема в том, что она не реализована.

Ответ 2

если вы посмотрите на лексический грамматический здесь

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 (формальный параметр-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

Нет места для запятых потому что язык написан таким образом, я не знаю причины, но адам знает