Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
CSharp Language Specification.doc
Скачиваний:
13
Добавлен:
26.09.2019
Размер:
4.75 Mб
Скачать

12.4Члены массива

В каждом типе массива наследуются члены, объявленные в классе System.Array.

12.5Ковариация массивов

Если для любых двух переменных A и B ссылочного типа выполняется неявное (§6.1.6) или явное преобразование ссылок (§6.2.4) из A в B, такое же преобразование ссылок доступно из массива A[R] в массив B[R], где R указывает спецификацию_ранга (одинаковую для обоих массивов). Эта связь называется ковариацией массивов. Ковариация массивов в частности означает, что значение с типом массива A[R] фактически может быть ссылкой на экземпляр типа массива B[R] при условии, что доступно неявное преобразование ссылок из B в A.

В связи с существованием ковариации массива при присваивании элементам массива ссылочного типа выполняется проверка времени выполнения, которая гарантирует, что присваиваемое элементу массива значение имеет допустимый тип (§7.17.1). Пример:

class Test { static void Fill(object[] array, int index, int count, object value) { for (int i = index; i < index + count; i++) array[i] = value; }

static void Main() { string[] strings = new string[100]; Fill(strings, 0, 100, "Undefined"); Fill(strings, 0, 10, null); Fill(strings, 90, 10, 0); } }

Присваивание массиву array[i] в методе Fill включает неявную проверку времени выполнения, гарантирующую, что объект, на который ссылается аргумент value, имеет значение null или является экземпляром типа, совместимого с фактическим типом элемента array. В методе Main первые два вызова метода Fill завершаются успешно, однако третий вызов этого метода приводит к возникновению исключения System.ArrayTypeMismatchException при выполнении первого присваивания массиву array[i]. Исключение возникает в связи с тем, что упакованное значение int не может храниться в массиве с типом string.

Ковариация массивов не расширяется до массивов типов_значений. Например, не существует преобразования, разрешающего использовать int[] как object[].

12.6Инициализаторы массива

Инициализаторы массива указываются в объявлениях полей (§10.5), объявлениях локальных переменных (§8.5.1) и выражениях создания массива (§7.6.10.4):

инициализатор_массива: { список_инициализаторов_переменныхнеобязательно } { список_инициализаторов_переменных , }

список_инициализаторов_переменных: инициализатор_переменной список_инициализаторов_переменных , инициализатор_переменной

инициализатор_переменных: выражение инициализатор_массива

Инициализатор массива состоит из последовательности переменных инициализаторов, заключенных в фигурные скобки «{» и «}» и разделенных запятыми «,». Каждый инициализатор переменной представляет собой выражение или (для многомерных массивов) инициализатор вложенного массива.

Контекст использования инициализатора массива определяет тип инициализируемого массива. В выражении создания массива тип массива непосредственно предшествует инициализатору или получается из выражений в инициализаторе массива. В объявлении поля или переменной тип массива представляет собой тип объявляемого поля или переменной. Если инициализатор массива используется в объявлении поля или переменной, например

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

он просто представляет собой краткую запись соответствующего выражения создания массива

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

Инициализатор одномерного массива должен состоять из последовательности выражений, позволяющих выполнять присваивание для типа элементов массива. Эти выражения инициализируют элементы массива в порядке по возрастанию, начиная с элемента с нулевым индексом. Число выражений в инициализаторе массива определяет длину создаваемого экземпляра массива. Например, приведенный выше инициализатор массива создает экземпляр массива int[] с длиной 5, а затем инициализирует этот экземпляр следующими значениями:

a[0] = 0; a[1] = 2; a[2] = 4; a[3] = 6; a[4] = 8;

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

int[,] b = {{0, 1}, {2, 3}, {4, 5}, {6, 7}, {8, 9}};

создает двумерный массив с длиной пять для левого измерения и с длиной два для правого измерения

int[,] b = new int[5, 2];

а затем инициализирует экземпляр массива следующими значениями:

b[0, 0] = 0; b[0, 1] = 1; b[1, 0] = 2; b[1, 1] = 3; b[2, 0] = 4; b[2, 1] = 5; b[3, 0] = 6; b[3, 1] = 7; b[4, 0] = 8; b[4, 1] = 9;

Если измерение, за исключением самого правого, имеет нулевую длину, предполагается, что все следующие измерения также имеют нулевую длину. В примере

int[,] c = {};

создает двухмерный массив с нулевой длиной для самого правого и самого левого измерения:

int[,] c = new int[0, 0];

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

int i = 3; int[] x = new int[3] {0, 1, 2}; // OK int[] y = new int[i] {0, 1, 2}; // Error, i not a constant int[] z = new int[3] {0, 1, 2, 3}; // Error, length/initializer mismatch

В этом примере инициализатор для переменной y приведет к возникновению ошибки компилирования, поскольку выражение длины массива не является константой. Инициализатор для переменной z также приведет к возникновению ошибки компилирования, поскольку заданная длина и число элементов в инициализаторе не совпадают.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]