Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Руководство_по_C#.doc
Скачиваний:
6
Добавлен:
01.07.2025
Размер:
10 Мб
Скачать
☆

4.5Создание динамического массива

Источник: csharpprogramming.ru, автор неизвестен

На днях мне попалась задача, для решения которой требовалось создать динамический массив. Обычно я привык вместо массивов использовать обобщенные списки List<T>, которые по умолчанию являются динамическими. Но, по условию задачи требовалось работать именно с массивом, который не является таковым, поэтому возникла небольшая проблема, решение которой описано в этой статье.

В языке C# под словом массив подразумевается объект с заранее заданным неизменяемым размером. То есть, к примеру, если Вы создали массив, который содержит пять элементов, то увеличить данный размер динамически Вы уже не сможете, так как он является фиксированным. В этом можно легко убедиться, воспользовавшись свойством IsFixedSize.

int [] numbers = new int [5];

bool fix = numbers.IsFixedSize; //true

С помощью данного свойства Вы можете определить, имеет ли созданный массив фиксированную длину. Если результатом является значение true, как в данном примере, то это значит, что мы не можем добавлять или удалять элементы в уже созданном массиве, то есть изменять его текущий размер. Но, при этом мы можем изменять его существующие элементы.

Так как задача довольно актуальная, то какой-то способ решения всё-таки должен быть. И он есть. Если Вам необходимо создать динамический массив, то Вы можете воспользоваться, например методом Resize класса System.Array.

static void Main(string [] args)

{

int length = 0;

int [] numbers = new int [5] {1,2,3,4,5};

length = numbers.Length; //5

Array.Resize<int>(ref numbers, 7);

//либо так

//Array.Resize(ref numbers, numbers.Length + 2);

length = numbers.Length; //7

Результат: {1,2,3,4,5,0,0} //- элементы

}

Данный метод принимает два параметра: имя массива и его новый размер. В ходе выполнения метода, будет создан новый массив указанной нами длины, после чего все значения из старого массива будут скопированы в него. В результате мы получаем динамический массив. Задача решена.

Либо мы можем схитрить и всё-таки решить данную задачу, воспользовавшись обобщенным списком List<T> класса System.Collections.Generic, например:

static void Main(string [] args)

{

int count = 0;

List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };

count = numbers.Count; //5

numbers.Add(6);

numbers.Add(7);

count = numbers.Count; //7

//преобразуем список в массив

int [] numbers2 = numbers.ToArray<int>();

}

Вместо массива мы используем список, который, как уже говорилось ранее, по умолчанию является динамическим. С помощью него мы выполняем всю необходимую работу и как только добиваемся нужного результата, то с помощью метода ToArray преобразуем список в массив.

4.6Массивы в качестве параметров

Массивы могут передаваться в методы в качестве параметров, а также возвращаться из методов. Для возврата массива достаточно объявить массив как тип возврата. Наглядно это показано в следующем примере:

using System;

namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

foreach (string s in myReturn())

Console.WriteLine(s);

int[] mySortArray = {4,1,2,5,3};

for (int i = 0; i <= 4; i++)

mySortArray[i] = mySort(mySortArray, i);

Console.WriteLine("\nОтсортированный массив:\n");

foreach (int i in mySortArray)

Console.Write("\t"+i);

Console.ReadLine();

}

// Данный метод возвращает массив Info

static Array myReturn()

{

string[] Info = {"Name","Family","Adress" };

return Info;

}

// Передача массива в метод в качестве параметра

// Данный метод возвращает значение одного из индексов

// отсортированного массива

static int mySort(Array sortArray, int i)

{

Array.Sort(sortArray);

return (int)sortArray.GetValue(i);

}

}

}

Результат работы данной программы:

Ковариантость массивов

Для массивов поддерживается ковариантность. Это значит, что массив может быть объявлен как базовый тип, и его элементам могут присваиваться элементы производных типов. Однако, стоит отметить, что ковариантность массивов возможна только для ссылочных типов, но не для типов значений.

Добавлю, что с ковариантностью массивов связана проблема, которая может быть решена только через исключения времени выполнения.

Структура ArraySegment<T>

Структура ArraySegment<T> представляет сегмент массива. Эта структура может применяться, когда нужно вернуть или передать методу части массива. Вместо передачи в метод массива, смещения и счетчика в отдельных параметрах, можно передать единственный параметр ArraySegment<T>. В этой структуре информация о сегменте (смещение и счетчик) заключена непосредственно в ее членах:

using System;

namespace ConsoleApplication1

{

class Program

{

static void Main(string[] args)

{

int[] arr1 = { 1, 2, 3, 4, 5, 6 };

int[] arr2 = { 7, 8, 9, 10 };

var mySegmentsArray = new ArraySegment<int>[3]

{

// Инициализируем сегменты массивов

new ArraySegment<int>(arr1,0,2),

new ArraySegment<int>(arr2,0,1),

new ArraySegment<int>(arr1,1,2)

};

Console.WriteLine("Сумма выбранных значений равна:\n"

+SumArraySegments(mySegmentsArray));

Console.ReadLine();

}

// Метод, вычисляющий сумму выбранных сегментов

static int SumArraySegments(ArraySegment<int>[] value)

{

int sum = 0;

foreach (var s in value)

for (int i = s.Offset; i < s.Offset + s.Count; i++)

sum += s.Array[i];

return sum;

}

}

}

Важно отметить, что сегменты массива не копируют элементы исходного массива. Вместо этого через ArraySegment<T> можно получить доступ к исходному массиву. Если изменяются элементы сегмента, то эти изменения будут видны в исходном массиве.