Почему этот фрагмент С# закончен?

Глупый вопрос, но зачем компилируется следующая строка?

int[] i = new int[] {1,};

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

Ответ 1

Я полагаю, что стандарт ECMA 334 говорит:

array-initializer:
    { variable-initializer-list(opt) }
    { variable-initializer-list , }
variable-initializer-list:
    variable-initializer
    variable-initializer-list , variable-initializer
variable-initializer:
    expression
    array-initializer

Как вы можете видеть, конечная запятая разрешена:

{ variable-initializer-list , }
                            ↑

P.S. за хороший ответ (даже если этот факт уже был отмечен многими пользователями).:)

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

Ответ 2

Это синтаксический сахар. В частности, такая запись может быть полезна при генерации кода.

int[] i = new int[] {
    1,
    2,
    3,
};

Кроме того, когда вы так пишете, чтобы добавить новую строку, вам нужно добавить текст только в одну строку.

Ответ 3

Он должен компилироваться по определению.

Нет второго элемента. Конечная запятая является допустимым синтаксисом при определении коллекции элементов.

i - это массив из int, содержащий один элемент, i[0], содержащий значение 1.

Ответ 4

Еще одно преимущество использования конечной запятой в сочетании с директивами препроцессора:

int[] i = new[] {
#if INCLUDE1
   1,
#endif

#if INCLUDE2
   2,
#endif

#if INCLUDE3
   3,
#endif
};

Без разрешения конечной запятой это было бы намного сложнее написать.

Ответ 5

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

int[] i = new[] { 
   someValue(),
   someOtherValue(),
   someOtherOtherValue(),

   // copy-pasted zomg! the commas don't hurt!
   someValue(),
   someOtherValue(),
   someOtherOtherValue(),

};

Ответ 6

То же самое относится к перечислениям:

enum Foo
{
  Bar,
  Baz,
};