Использование инициализатора массива '{}' несколько раз для одной и той же переменной не компилируется - PullRequest
8 голосов
/ 04 августа 2010

Я пытаюсь скомпилировать следующий код в 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};

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

Ответы [ 7 ]

10 голосов
/ 04 августа 2010

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

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) часть объявления.

5 голосов
/ 04 августа 2010

C # spec 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"};

нет.

2 голосов
/ 04 августа 2010

Ошибка компилятора, на которую вы ссылаетесь, вызвана синтаксисом 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 голосов
/ 04 августа 2010

Как и на той же странице MSDN, этот синтаксис специфичен для инициализации переменной массива; это не синтаксис массива общего назначения.

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

String[] words = { "Hello", "Worlds" };
// words = {"Foo", "Bar"};
words = new[] {"Foo", "Bar"};
1 голос
/ 04 августа 2010

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

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

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

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

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


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

1 голос
/ 04 августа 2010

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

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

0 голосов
/ 04 августа 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...