System.Array
Тип System.Array является абстрактным базовым типом для всех типов массива. Выполняется неявное преобразование ссылок (§6.1.6) из любого типа в тип System.Array, а также явное преобразование ссылок (§6.2.4) из типа System.Array в любой тип массива. Обратите внимание, что тип System.Array сам по себе не является типом_массива;. Это тип_класса, на основе которого создаются все типы_массива;. Во время выполнения значение с типом System.Array может быть равным null или содержать ссылку на экземпляр с любым типом массива. IList В одномерном массиве T[] реализуется интерфейс System.Collections.Generic.IList<T> (сокращенно IList<T>) и его базовые интерфейсы. В связи с этим выполняется неявное преобразование из T[] в IList<T> и его базовые интерфейсы. В дополнение к этому при наличии неявного преобразования ссылок из S в T в массиве S[] реализуется интерфейс IList<T> и выполняется неявное преобразование ссылок из S[] в IList<T> и его базовые интерфейсы (§6.1.6). При наличии явного преобразования ссылок из S в T выполняется явное преобразование ссылок из S[] в IList<T> и его базовые интерфейсы (§6.2.4). Пример: using System.Collections.Generic; class Test IList<string> lst1 = sa; // Ok IList<string> lst5 = (IList<string>)oa1; // Exception Присваивание lst2 = oa1 приведет к ошибке компилирования, поскольку преобразование из object[] в IList<string> должно быть явным и не может выполняться неявно. Приведение типов в строке (IList<string>)oa1 приведет к созданию исключения во время выполнения, так как переменная oa1 ссылается на объект object[], а не на объект string[]. Тем не менее приведение типов (IList<string>)oa2 не приведет к созданию исключения, поскольку переменная oa2 ссылается на объект string[]. При выполнении явного или неявного преобразования ссылок из S[] в IList<T> также выполняется явное преобразование ссылок из интерфейса IList<T> и его базовых интерфейсов в S[] (§6.2.4). Если в типе массива S[] реализуется интерфейс IList<T>, некоторые из членов реализованного интерфейса могут создавать исключения. Описание точного поведения этой реализации интерфейса выходит за рамки настоящей спецификации. 12.2 Создание массива; Экземпляры массива создаются при помощи выражений_создания_массива; (§7.6.10.4) либо путем объявлений полей или локальных переменных, содержащих инициализатор_массива; (§12.6). Ранг массива и длина каждого из его измерений устанавливаются при создании экземпляра массива и остаются неизменными в течение всего времени жизни этого экземпляра. Другими словами, нельзя изменить ранг массива или длину его измерений. Экземпляр массива всегда имеет тип массива. Тип System.Array является абстрактным типом, создание экземпляров непосредственно с этим типом невозможно. Элементы массива, созданного с использованием выражений_создания_массива;, всегда инициализируются значениями по умолчанию (§5.2). 12.3 Доступ к элементам массива Доступ к элементам массива осуществляется при помощи выражений доступа_к_элементам; (§7.6.6.1) в форме A[I1, I2,..., IN], где A является выражением с типом массива, а каждый элемент IX — выражением с типом int, uint, long, ulong либо может быть неявно преобразован в один или несколько из этих типов. Результатом осуществления доступа к элементу массива является переменная, а именно элемент массива, выбранный по индексу. Элементы массива могут перечисляться с использованием оператора foreach (§8.8.4). 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 Main() { Присваивание массиву 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; Если измерение, за исключением самого правого, имеет нулевую длину, предполагается, что все следующие измерения также имеют нулевую длину. В примере int[,] c = {}; создает двухмерный массив с нулевой длиной для самого правого и самого левого измерения: int[,] c = new int[0, 0]; Если при создании массива выражение содержит как явное указание длины измерений, так и инициализатор массива, длина должна быть выражена в константах, а количество элементов на каждом уровне вложенности должно совпадать с длиной соответствующего измерения. Примеры: int i = 3; В этом примере инициализатор для переменной y приведет к возникновению ошибки компилирования, поскольку выражение длины массива не является константой. Инициализатор для переменной z также приведет к возникновению ошибки компилирования, поскольку заданная длина и число элементов в инициализаторе не совпадают.
13. Интерфейсы; В интерфейсе определяется контракт. Класс или структура, в которых реализуется этот интерфейс, должны соблюдать условия данного контракта. Интерфейс может наследовать из нескольких базовых интерфейсов, а в классе или структуре может быть реализовано несколько интерфейсов. Интерфейсы могут содержать методы, свойства, события и индексаторы. Сам интерфейс не содержит реализации для определяемых им членов. Интерфейс всего лишь указывает члены, которые должны быть определены в классах или структурах, реализующих этот интерфейс. 13.1 Объявления интерфейсов Объявление_интерфейса; является объявлением_типа; (§9.6), где объявляется новый тип интерфейса. объявление_интерфейса: Объявление_интерфейса; состоит из необязательного набора атрибутов; (§17), за которым следуют необязательный набор модификаторов_интерфейса; (§13.1.1), необязательный модификатор partial, ключевое слово interface и идентификатор;, именующий интерфейс, необязательная спецификация списка_параметров_типа_варианта; (§13.1.3), необязательная спецификация базы_интерфейса; (§13.1.4), необязательная спецификация предложений_ограничений_параметров_типов; (§10.1.5) и тело_интерфейса; (§13.1.5), которое может завершаться точкой с запятой. 13.1.1 Модификаторы интерфейса Объявление_интерфейса; может включать последовательность модификаторов интерфейса: модификаторы_интерфейса: модификатор_интерфейса: Включение одного модификатора в объявление интерфейса несколько раз приведет к возникновению ошибки при компилировании. Модификатор new разрешен только в том случае, если интерфейс определяется внутри класса. Он указывает, что в интерфейсе скрыт унаследованный член с таким же именем (см. §10.3.4). Модфикаторы public, protected, internal и private управляют доступом к интерфейсу. Допустимые модификаторы определяются контекстом объявления интерфейса (§3.5.1).
|