Массив — фиксированный набор элементов одного типа. Массив — ссылочный тип. Элементы массива всегда хранятся в смежных областях памяти, что обеспечивает крайне эффективный доступ к ним.
Массив обозначается квадратными скобками после типа элемента. В скобках указывается размер массива:
| 1 | char[] vowels = new char[5]; | 
Квадратные скобки также служат указателем массива, обеспечивая доступ к его элементам по их позиции:
| 1 2 3 | vowels[0] = 'a'; vowels[1] = 'e'; vowels[2] = 'i'; vowels[3] = 'o'; vowels[4] = 'u'; Console.WriteLine (vowels [1]); // e | 
Массив индексируется с нуля.
С помощью инструкции for можно перебрать все элементы массива:
| 1 | for (int i = 0; i < vowels.Length; i++) Console.Write (vowels [i]); // aeiou | 
 Массив также реализует интерфейс IEnumerable<T>, в силу чего можно перечислять его элементы с помощью инструкции foreach:
| 1 | foreach (char c in vowels) Console.Write (c); // aeiou | 
 Если попытаться обратиться к несуществующему элементу массива во время выполнения возникнет ошибка IndexOutOfRangeException.
Свойство массива Length возвращает общее число элементов массива. После создания массива его размер изменять уже нельзя. В пространстве имен System.Collection содержаться структуры, такие как динамические массивы и словари (dictionarues), размер которых можно менять.
Массив можно заполнить сразу при инициализации:
| 1 | char[] vowels = new char[] {'a','e','i','o','u'}; | 
или даже проще:
| 1 | char[] vowels = {'a','e','i','o','u'}; | 
Все массивы наследуются от класса System.Array, который определяет ряд общих методов и свойств для всех массивов:
- свойство LengthиRank
- метод CreateInstance, позволяющий динамически создавать массивы
- методы GetValue/SetValue, позволяющие получать и устанавливать элементы массива невзирая на его тип
- метод BinarySearch, выполняющий поиск в сортированном массиве
- методы IndexOf,LastIndexOf,Find,FindIndex,FindLastIndex, выполняющие поиск в несортированном массиве
- метод Sort, сортирующий массив
- метод Copy, копирующий массив
Элементы вновь созданного, но еще не заполненного массива, автоматически заполняются значениями по умолчанию. Значения по умолчанию — это результат бинарного обнуления памяти для каждого конкретного типа. Например для целых чисел значением по умолчанию будет 0, для ссылочных типов — null.
Многомерные массивы
Существует два вида многомерных массивов: прямоугольный (rectangular) массив и невыровненный (jagged) массив.
Прямоугольный (rectangular) массив — представляет собой блок памяти с n-ым количеством измерений. Прямоугольный массив определяется с использованием запятых, которые отделяю его измерения:
| 1 | int[,] matrix = new int [3, 3]; // Двух-мерный массив размером 3 х 3 | 
Метод GetLength принимает в качестве аргумента индекс измерения и возвращает его длину:
| 1 2 3 4 5 6 7 | for (int i = 0; i < matrix.GetLength(0); i++) {     for (int j = 0; j < matrix.GetLength(1); j++)     {         matrix [i, j] = i * 3 + j;     } } | 
Прямоугольный массив может быть инициализирован сразу при объявлении:
| 1 2 3 4 5 6 | int[,] matrix = new int[,] {     {0,1,2},     {3,4,5},     {6,7,8} }; | 
 При этом конструкцию new int[,] (выделена жирным) можно опустить.
Невыровненный (jagged) массив — это массив массивов. Невыровненный массив объявляется с помощью идущих друг за другом пар квадратных скобок:
| 1 | int[][] matrix = new int[3][]; // Двух-мерный массив, внешнее измерение равно трем | 
 Внутреннее измерение при объявлении не указывается, поскольку в отличие от прямоугольного массива, в невыровненном каждый внутренний массив может иметь разную длину. Каждому внутреннему массиву автоматически присваивается значение null, а не пустой массив, и поэтому каждый внутренний массив нужно объявлять отдельно.
Невыровненный массив также может быть инициализирован при объявлении:
| 1 2 3 4 5 6 | int[][] matrix = new int[][] {     new int[] {0,1,2},     new int[] {3,4,5},     new int[] {6,7,8,9} }; | 
 Конструкцию new int[][] (выделена жирным) также можно опустить.
Упрощенная инициализация массива
Существует два способа упрощенной инициализации массива. Первый уже был рассмотрен выше и состоит в том что можно опустить ключевое слово new:
| 1 2 | char[] vowels = new char[] {'a','e','i','o','u'}; char[] vowels =            {'a','e','i','o','u'}; | 
new и дать компилятору возможность угадать тип самому. Это сокращение полезно при передаче массива в качестве аргумента. При этом массив можно создавать налету:| 1 2 3 | void Foo (char[] data) { ... } // Объявляем метод Foo ( new char[] {'a','e','i','o','u'} ); // Полная запись Foo ( new[]      {'a','e','i','o','u'} ); // Сокращенная запись | 

