C# Language
Массивы
Поиск…
Синтаксис
Объявление массива:
<тип> [] <имя>;
Объявление двумерного массива:
<тип> [,] <имя> = новый <тип> [<значение>, <значение>];
Объявление Jagged Array:
<тип> [] <имя> = новый <тип> [<значение>];
Объявление subarray для Jagged Array:
<name> [<значение>] = новый <тип> [<значение>];
Инициализация массива без значений:
<name> = new <тип> [<длина>];
Инициализация массива со значениями:
<name> = new <type> [] {<значение>, <значение>, <значение>, ...};
Инициализация двумерного массива со значениями:
<name> = new <type> [,] {{<значение>, <значение>}, {<значение>, <значение>}, ...};
Доступ к элементу с индексом i:
<Имя> [я]
Получение длины массива:
<Имя> .Length
замечания
В C # массив является ссылочным типом, что означает, что он имеет значение NULL .
Массив имеет фиксированную длину, что означает, что вы не можете его использовать .Add()
или .Remove()
. Чтобы использовать их, вам понадобится динамический массив - List
или ArrayList
.
Ковариантность массива
string[] strings = new[] {"foo", "bar"};
object[] objects = strings; // implicit conversion from string[] to object[]
Это преобразование не является безопасным для типов. Следующий код вызовет исключение во время выполнения:
string[] strings = new[] {"Foo"};
object[] objects = strings;
objects[0] = new object(); // runtime exception, object is not string
string str = strings[0]; // would have been bad if above assignment had succeeded
Получение и установка значений массива
int[] arr = new int[] { 0, 10, 20, 30};
// Get
Console.WriteLine(arr[2]); // 20
// Set
arr[2] = 100;
// Get the updated value
Console.WriteLine(arr[2]); // 100
Объявление массива
Массив может быть объявлен и заполнен значением по умолчанию с использованием синтаксиса инициализации с квадратной скобкой ( []
). Например, создавая массив из 10 целых чисел:
int[] arr = new int[10];
Индексы в C # основаны на нуле. Индексы массива выше будут 0-9. Например:
int[] arr = new int[3] {7,9,4};
Console.WriteLine(arr[0]); //outputs 7
Console.WriteLine(arr[1]); //outputs 9
Это означает, что система начинает подсчет индекса элемента из 0. Более того, доступ к элементам массивов выполняется в постоянное время . Это означает, что доступ к первому элементу массива имеет одинаковую стоимость (по времени) доступа к второму элементу, третьему элементу и так далее.
Вы также можете объявить ссылку на массив без создания экземпляра массива.
int[] arr = null; // OK, declares a null reference to an array.
int first = arr[0]; // Throws System.NullReferenceException because there is no actual array.
Массив также может быть создан и инициализирован с помощью пользовательских значений с использованием синтаксиса инициализации коллекции:
int[] arr = new int[] { 24, 2, 13, 47, 45 };
new int[]
может быть опущена при объявлении переменной массива. Это не самодостаточное выражение , поэтому использование его как части другого вызова не работает (для этого используйте версию с new
):
int[] arr = { 24, 2, 13, 47, 45 }; // OK
int[] arr1;
arr1 = { 24, 2, 13, 47, 45 }; // Won't compile
Неявно типизированные массивы
В качестве альтернативы, в сочетании с ключевым словом var
, конкретный тип может быть опущен так, чтобы был выведен тип массива:
// same as int[]
var arr = new [] { 1, 2, 3 };
// same as string[]
var arr = new [] { "one", "two", "three" };
// same as double[]
var arr = new [] { 1.0, 2.0, 3.0 };
Итерация по массиву
int[] arr = new int[] {1, 6, 3, 3, 9};
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
используя foreach:
foreach (int element in arr)
{
Console.WriteLine(element);
}
использование небезопасного доступа с указателями https://msdn.microsoft.com/en-ca/library/y31yhkeb.aspx
unsafe
{
int length = arr.Length;
fixed (int* p = arr)
{
int* pInt = p;
while (length-- > 0)
{
Console.WriteLine(*pInt);
pInt++;// move pointer to next element
}
}
}
Выход:
1
6
3
3
9
Многомерные массивы
Массивы могут иметь более одного измерения. В следующем примере создается двумерный массив из десяти строк и десяти столбцов:
int[,] arr = new int[10, 10];
Массив из трех измерений:
int[,,] arr = new int[10, 10, 10];
Вы также можете инициализировать массив после объявления:
int[,] arr = new int[4, 2] { {1, 1}, {2, 2}, {3, 3}, {4, 4} };
// Access a member of the multi-dimensional array:
Console.Out.WriteLine(arr[3, 1]); // 4
Жесткие массивы
Жесткие массивы - это массивы, которые вместо примитивных типов содержат массивы (или другие коллекции). Это похоже на массив массивов - каждый элемент массива содержит другой массив.
Они похожи на многомерные массивы, но имеют небольшую разницу - поскольку многомерные массивы ограничены фиксированным числом строк и столбцов, с зубчатыми массивами, каждая строка может иметь различное количество столбцов.
Объявление зубчатого массива
Например, объявив зубчатый массив с 8 столбцами:
int[][] a = new int[8][];
Второй []
инициализируется без номера. Чтобы инициализировать вспомогательные массивы, вам нужно будет сделать это отдельно:
for (int i = 0; i < a.length; i++)
{
a[i] = new int[10];
}
Получение / установка значений
Теперь получить один из подмассивов легко. Давайте печатать все цифры 3 - го столбца : a
for (int i = 0; i < a[2].length; i++)
{
Console.WriteLine(a[2][i]);
}
Получение определенного значения:
a[<row_number>][<column_number>]
Установка определенного значения:
a[<row_number>][<column_number>] = <value>
Помните : всегда рекомендуется использовать зубчатые массивы (массивы массивов), а не многомерные массивы (матрицы). Это быстрее и безопаснее.
Обратите внимание на порядок скобок
Рассмотрим трехмерный массив пятимерных массивов одномерных массивов int
. Это написано на C # как:
int[,,][,,,,][] arr = new int[8, 10, 12][,,,,][];
В системе типа CLR соглашение для упорядочения скобок отменяется, поэтому с приведенным выше экземпляром arr
мы имеем:
arr.GetType().ToString() == "System.Int32[][,,,,][,,]"
и аналогичным образом:
typeof(int[,,][,,,,][]).ToString() == "System.Int32[][,,,,][,,]"
Проверка того, содержит ли один массив другой массив
public static class ArrayHelpers
{
public static bool Contains<T>(this T[] array, T[] candidate)
{
if (IsEmptyLocate(array, candidate))
return false;
if (candidate.Length > array.Length)
return false;
for (int a = 0; a <= array.Length - candidate.Length; a++)
{
if (array[a].Equals(candidate[0]))
{
int i = 0;
for (; i < candidate.Length; i++)
{
if (false == array[a + i].Equals(candidate[i]))
break;
}
if (i == candidate.Length)
return true;
}
}
return false;
}
static bool IsEmptyLocate<T>(T[] array, T[] candidate)
{
return array == null
|| candidate == null
|| array.Length == 0
|| candidate.Length == 0
|| candidate.Length > array.Length;
}
}
/// Образец
byte[] EndOfStream = Encoding.ASCII.GetBytes("---3141592---");
byte[] FakeReceivedFromStream = Encoding.ASCII.GetBytes("Hello, world!!!---3141592---");
if (FakeReceivedFromStream.Contains(EndOfStream))
{
Console.WriteLine("Message received");
}
Инициализация массива, заполненного повторным значением, отличным от значения по умолчанию
Как мы знаем, мы можем объявить массив со значениями по умолчанию:
int[] arr = new int[10];
Это создаст массив из 10 целых чисел с каждым элементом массива, имеющим значение 0
(значение по умолчанию для типа int
).
Чтобы создать массив, инициализированный значением, отличным от значения по умолчанию, мы можем использовать Enumerable.Repeat
из пространства имен System.Linq
:
Чтобы создать массив
bool
размером 10, заполненный «истинным»,bool[] booleanArray = Enumerable.Repeat(true, 10).ToArray();
Чтобы создать массив
int
размером 5, заполненный «100»,int[] intArray = Enumerable.Repeat(100, 5).ToArray();
Чтобы создать массив
string
размером 5, заполненный «C #»,string[] strArray = Enumerable.Repeat("C#", 5).ToArray();
Копирование массивов
Копирование частичного массива со статическим Array.Copy()
, начинающимся с индекса 0 в обоих источниках и источниках:
var sourceArray = new int[] { 11, 12, 3, 5, 2, 9, 28, 17 };
var destinationArray= new int[3];
Array.Copy(sourceArray, destinationArray, 3);
// destinationArray will have 11,12 and 3
Копирование всего массива с CopyTo()
экземпляра экземпляра CopyTo()
, начинающегося с индекса 0 источника и указанного индекса в получателе:
var sourceArray = new int[] { 11, 12, 7 };
var destinationArray = new int[6];
sourceArray.CopyTo(destinationArray, 2);
// destinationArray will have 0, 0, 11, 12, 7 and 0
Clone
используется для создания копии объекта массива.
var sourceArray = new int[] { 11, 12, 7 };
var destinationArray = (int)sourceArray.Clone();
//destinationArray will be created and will have 11,12,17.
Оба CopyTo
и Clone
выполняют мелкую копию, что означает, что содержимое содержит ссылки на тот же объект, что и элементы в исходном массиве.
Создание массива последовательных чисел
LINQ предоставляет метод, который упрощает создание коллекции, заполненной последовательными номерами. Например, вы можете объявить массив, который содержит целые числа от 1 до 100.
Метод Enumerable.Range
позволяет нам создавать последовательность целых чисел из заданной начальной позиции и нескольких элементов.
Метод принимает два аргумента: начальное значение и количество генерируемых элементов.
Enumerable.Range(int start, int count)
Обратите внимание, что count
не может быть отрицательным.
Использование:
int[] sequence = Enumerable.Range(1, 100).ToArray();
Это создаст массив, содержащий числа от 1 до 100 ( [1, 2, 3, ..., 98, 99, 100]
).
Поскольку метод Range
возвращает IEnumerable<int>
, мы можем использовать другие методы LINQ на нем:
int[] squares = Enumerable.Range(2, 10).Select(x => x * x).ToArray();
Это создаст массив, содержащий 10 целых квадратов, начиная с 4
: [4, 9, 16, ..., 100, 121]
.
Сравнение массивов для равенства
LINQ предоставляет встроенную функцию для проверки равенства двух IEnumerable
s, и эта функция может использоваться на массивах.
Функция SequenceEqual
вернет true
если массивы имеют одинаковую длину, а значения в соответствующих индексах равны, а false
противном случае.
int[] arr1 = { 3, 5, 7 };
int[] arr2 = { 3, 5, 7 };
bool result = arr1.SequenceEqual(arr2);
Console.WriteLine("Arrays equal? {0}", result);
Это напечатает:
Arrays equal? True
Массивы как IEnumerable <> экземпляры
Все массивы реализуют неосновный интерфейс IList
(и, следовательно, не общие базовые интерфейсы ICollection
и IEnumerable
).
Что еще более важно, одномерные массивы реализуют IList<>
и IReadOnlyList<>
общие интерфейсы (и их базовые интерфейсы) для типа данных, которые они содержат. Это означает, что их можно рассматривать как общие перечислимые типы и передавать в различные методы без необходимости сначала преобразовывать их в форму без массива.
int[] arr1 = { 3, 5, 7 };
IEnumerable<int> enumerableIntegers = arr1; //Allowed because arrays implement IEnumerable<T>
List<int> listOfIntegers = new List<int>();
listOfIntegers.AddRange(arr1); //You can pass in a reference to an array to populate a List.
После запуска этого кода список listOfIntegers
будет содержать List<int>
содержащий значения 3, 5 и 7.
Массивы средств поддержки IEnumerable<>
могут быть запрошены с помощью LINQ, например arr1.Select(i => 10 * i)
.