инициализация элементов массива
В предыдущем разделе рассмотрена процедура создания элементов массива
и присвоения им начальных значений. Синтаксис C# позволяет совместить эти
операции:
String[] names = new String[] { "Aidan", "Grant" };
Набор разделенных запятой символов в фигурных скобках называется
иници-
ализатором массива
(array initializer). Сложность каждого символа может быть
419
Инициализация.элементов.массива
произвольной, а в случае многомерного массива инициализатор может оказаться
вложенным. В показанном примере фигурируют всего два простых выражения
типа
String
.
Если в методе объявляется локальная переменная для работы с инициализи-
рованным массивом, для упрощения кода можно воспользоваться переменной
неявного типа
var
:
// Использование локальной переменной неявного типа:
var names = new String[] { "Aidan", "Grant" };
В результате компилятор делает вывод о том, что локальная переменная
names
относится к типу
String[]
, так как именно к этому типу принадлежит выражение,
расположенное справа от оператора присваивания (
=
). Используя неявную типиза-
цию массивов C#, вы поручаете компилятору определить тип элементов массива.
Обратите внимание на отсутствие спецификации типа между операторами
new
и
[]
в следующем фрагменте кода:
// Задание типа массива с помощью локальной переменной неявного типа:
var names = new[] { "Aidan", "Grant", null };
Компилятор определяет тип выражений, используемых для инициализации
элементов массива, и по результатам выбирает базовый класс, который лучше
всего описывает все элементы. В показанном примере компилятор обнаруживает
два элемента типа
String
и значение
null
. Но так как последнее может быть не-
явно преобразовано в любой ссылочный тип, выбор делается в пользу создания
и инициализации массива ссылок типа
String
.
Еще пример:
// Ошибочное задание типа массива с помощью локальной
// переменной неявного типа
var names = new[] { "Aidan", "Grant", 123 };
На такой код компилятор реагирует сообщением (ошибка CS0826: подходящего
типа для неявно заданного массива не обнаружено):
error CS0826: No best type found for implicitly-typed array
Дело в том, что общим базовым типом для двух строк и значения типа
Int32
является тип
Object
. Для компилятора это означает необходимость создать массив
ссылок типа
Object
, а затем упаковать значение типа
Int32
и заставить последний
элемент массива ссылаться на результат упаковки, имеющий значение 123. Раз-
работчики сочли, что задача упаковки элементов массива приводит к слишком
высоким затратам, чтобы компилятор мог выполнять ее неявно, поэтому в такой
ситуации просто выводится сообщение об ошибке.
В качестве синтаксического бонуса можно указать возможность вот такой ини-
циализации массива:
String[] names = { "Aidan", "Grant" };
Обратите внимание, что справа от оператора присваивания располагаются только
начальные значения элементов массива. Ни оператора
new
, ни типа, ни квадратных
420
Глава.16 .Массивы
скобок там нет. Этот синтаксис удобен, но к сожалению, в этом случае компилятор
не разрешает использовать локальные переменные неявного типа:
// Ошибочное использование локальной переменной
var names = { "Aidan", "Grant" };
Попытка компиляции такой строчки приведет к появлению двух сообщений:
error CS0820: Cannot initialize an implicitly-typed local variable with
an array initializer
error CS0622: Can only use array initializer expressions to assign array types.
Try using a new expression instead
Первое говорит о том, что локальной переменной неявного типа невозможно
присвоить начальное значение при помощи инициализатора массива, а второе
информирует, что данный инициализатор применяется только для назначения
типов массивам и рекомендует вам воспользоваться оператором
new
. В принципе,
компилятор вполне способен выполнить все эти действия самостоятельно, но раз-
работчики решили, что это — слишком сложная задача. Ведь пришлось бы опреде-
лять тип массива, создавать его при помощи оператора
new
, присваивать элементам
начальные значения, а кроме того, определять тип локальной переменной.
Напоследок хотелось бы рассмотреть процедуру неявного задания типа массива
в случае анонимных типов и локальных переменных неявного типа. (Об анонимных
типах см. главу 10.)
Рассмотрим следующий код:
// Применение переменных и массивов неявно заданного типа,
// а также анонимного типа:
var kids = new[] {new { Name="Aidan" }, new { Name="Grant" }};
// Пример применения (с другой локальной переменной неявно заданного типа):
foreach (var kid in kids)
Console.WriteLine(kid.Name);
В этом примере для присваивания начальных значений элементам массива ис-
пользуются два выражения, каждое из которых представляет собой анонимный тип
(ведь после оператора
new
ни в одном из случаев не фигурирует имя типа). Благо-
даря идентичной структуре этих выражений (поле
Name
типа
String
) компилятор
относит оба объекта к одному типу. Теперь мы можем воспользоваться возможно-
стью неявного задания типа массива (когда между оператором
new
и квадратными
скобками отсутствует имя типа). В результате компилятор самостоятельно опре-
делит тип, сконструирует массив и инициализирует его элементы как ссылки на
два экземпляра одного и того же анонимного типа. В итоге ссылка на этот объект
присваивается локальной переменной
kids
, тип которой определит компилятор.
Затем только что созданный и инициализированный массив используется в ци-
кле
foreach
, в котором фигурирует и переменная
kid
неявного типа. Вот результат
выполнения такого кода:
Aidan
Grant
Do'stlaringiz bilan baham: |