Глупый вопрос, но почему следующая строка компилирует?
int[] i = new int[] {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. за хороший ответ (даже если на этот факт уже указали многие пользователи). :)
Конечная запятая может использоваться для упрощения реализации автоматических генераторов кода (генераторы могут избежать проверки последнего элемента в инициализаторе, поскольку он должен быть написан без запятой) и условной инициализации массива с помощью директив препроцессора.
Он должен компилироваться по определению.
Второго элемента нет. Завершающая запятая является допустимым синтаксисом при определении коллекции элементов.
i
- это массив int
, содержащий единственный элемент i [0]
, содержащий значение 1
.
Это так, чтобы вы могли делать это и копировать / вставлять строки, не беспокоясь об удалении / добавлении запятых в нужных местах.
int[] i = new[] {
someValue(),
someOtherValue(),
someOtherOtherValue(),
// copy-pasted zomg! the commas don't hurt!
someValue(),
someOtherValue(),
someOtherOtherValue(),
};
Это синтаксический сахар. В частности, такая запись может быть полезна при генерации кода.
int[] i = new int[] {
1,
2,
3,
};
Кроме того, когда вы пишете так, чтобы добавить новую строку, вам нужно добавить текст только в одну строку.
То же самое касается перечислений:
enum Foo
{
Bar,
Baz,
};
Еще одно преимущество разрешения запятой после запятой - в сочетании с директивами препроцессора:
int[] i = new[] {
#if INCLUDE1
1,
#endif
#if INCLUDE2
2,
#endif
#if INCLUDE3
3,
#endif
};
Без разрешения запятой после запятой это было бы гораздо труднее написать.