Использование инициализатора массива '{}' несколько раз для одной и той же переменной не компилируется

Я пытаюсь скомпилировать следующий код на C #:

String[] words = {"Hello", "Worlds"};
words = {"Foo", "Bar"};

И я получаю такие ошибки компиляции, как:

Error 1 Invalid expression term '{'
Error 2 ; expected
Error 3 Invalid expression term ','

С другой стороны, если я попробую

String[] words = { "Hello", "Worlds" };
words = new String[] {"Foo", "Bar"};

Он компилируется нормально. Согласно MSDN ,

int[] a = {0, 2, 4, 6, 8};

это просто сокращение для эквивалентного выражения создания массива:

int[] a = new int[] {0, 2, 4, 6, 8};

Почему не компилируется первый пример кода?

8
задан Peter Mortensen 7 May 2017 в 14:05
поделиться

7 ответов

Спецификация C # 12.6 Инициализаторы массивов

В объявлении поля или переменной тип массива - это тип объявляемого поля или переменной. Когда инициализатор массива используется в объявлении поля или переменной, например: int [] a = {0, 2, 4, 6, 8}; это просто сокращение для эквивалентного выражения создания массива: int [] a = new int [] {0, 2, 4, 6, 8};

String[] words = { "Hello", "Worlds" };

- это объявление, а

words = {"Foo", "Bar"};

- нет.

5
ответ дан 5 December 2019 в 07:56
поделиться

Согласно той же странице MSDN, этот синтаксис специфичен для инициализации переменной массива; это не универсальный синтаксис массива.

Однако это близко:

String[] words = { "Hello", "Worlds" };
// words = {"Foo", "Bar"};
words = new[] {"Foo", "Bar"};
2
ответ дан 5 December 2019 в 07:56
поделиться

Согласно документам, с которыми вы связались, инициализаторы массива действительны только сами по себе в объявлениях полей или переменных - для присвоения переменных вы должны заранее указать new [] :

В ] выражение создания массива (общий случай), тип массива непосредственно предшествует инициализатору. В объявлении поля или переменной тип массива - это тип объявляемого поля или переменной.

1
ответ дан 5 December 2019 в 07:56
поделиться

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

В C # 3 вы можете использовать слегка сокращенную форму:

words = new[] {"Foo", "Bar"};

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

Однако нет возможности использовать «полностью сокращенную» форму вне объявления переменных.


1 Конечно, есть некоторые выражения, не имеющие типа, например лямбда-выражения.

1
ответ дан 5 December 2019 в 07:56
поделиться

Во время инициализации вы явно объявляете тип массива, что делает это сокращение ясным и недвусмысленным. Однако позже в коде начинает закрадываться небольшая двусмысленность. Теоретически вы могли бы, например, попытаться создать массив объектов. Конечно, вы , вероятно, хотите, чтобы это был массив строк, но во избежание логических ошибок компилятор не хочет предполагать что-то подобное, если не совсем ясно, что вы пытаетесь сделать. .

0
ответ дан 5 December 2019 в 07:56
поделиться

Ошибка компилятора, о которой вы говорите, вызвана синтаксисом invaild.

// variable declaration so constructor may be assumed
String[] words = { "Hello", "Worlds" }; 

// attempted variable assignment using invalid syntax
words = {"Foo", "Bar"}; 

// explicit constructor
words = new String[] {"Foo", "Bar"};

// as a note this would also work.  Here the type of the array is assumed.
words = new [] {"Foo", "Bar"};
2
ответ дан 5 December 2019 в 07:56
поделиться

Правильно, синтаксис короткого инициализатора разрешен только в объявлении. Не в обычном операторе.

String[] words = new string[]{ "Hello", "Worlds" }; // full form
String[] words = { "Hello", "Worlds" };  // short hand, special rule
words = {"Foo", "Bar"};                  // not allowed
words = new String[] {"Foo", "Bar"};     // allowed, full form again

Краткое обозначение разрешено только тогда, когда оно используется как (rhs) часть объявления.

10
ответ дан 5 December 2019 в 07:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: