Как добавить размер у имеющегося массива
Всем привет! Сегодня встал вопрос, о добавление к имеющемуся массиву размер. Почитай статьи, я понял, что нужно юзать List, это правильно и удобно, НО у меня всё уже было построено на массивах и если изменять это, то это займёт кучу времени!
НО, я - это гений (сарказм) и у меня получилось добавить к текущему массиву новую ячейку.
Ответы (2 шт):
И так, вот мой код:
public string[] addMassiv(string[] old_massiv, int add) //первый параметр - массив, второй - сколько вы хотите добавить ячеек
{
string[] new_massiv = new string[old_massiv.Length + add];
for (int x = 0; x < old_massiv.Length; x++)
new_massiv[x] = old_massiv[x]; //переписываем старые данные в новый массив
return new_massiv;
}
Просто подставьте нужный вам тип данных вместо string[]
вот пример использования:
string[] sg = new string[1];
sg[0] = "чёто там";
sg = addMassiv(sg, 1);
sg[1] = "чёто там 2";
Console.WriteLine(sg[0] + " " + sg[1]);
Массивы следует использовать там, где известно количество элементов создаваемой коллекции. Если же количество неизвестно, лучше использовать List<T>, потому что он лучше оптимизирован для добавления в него элементов. Технически под списко лежит тот же массив, и он ему так же делает Array.Resize, когда ему не хватает место, но он делает это на упреждение, к примеру, в списке менее 16 элементов, а массив там на 16, а когда вы добавляете 17-й элемент, список увеличивает несущий данные массив аж сразу в 2 раза, и так далее. То есть медленное по производительности изменение размеров массива вызывается далеко не каждый раз, когда вы добавляете элемент.
Следовательно, и логика вашего метода расширения массива может быть схожая. Если абстрагироваться от того, что есть в .NET и представить, что существует только массив, то то, чего вы хотели добиться, можно сделать создав свой "список" следующим образом.
public class MyList<T> : IEnumerable<T>
{
private T[] _array;
private int _count;
public T this[int index]
{
get
{
CheckIndex(index);
return _array[index];
}
set
{
CheckIndex(index);
_array[index] = value;
}
}
public int Count => _count;
public MyList() : this(16) { }
public MyList(int count)
{
_array = new T[count];
}
public MyList(IEnumerable<T> source)
{
_array = source.ToArray();
_count = _array.Length;
}
private void CheckIndex(int index)
{
if (index < 0 || index >= _count)
throw new IndexOutOfRangeException();
}
public void Add(T item)
{
if (_array.Length == _count)
Array.Resize(ref _array, _count * 2);
_array[_count] = item;
_count++;
}
private IEnumerable<T> Enumerate()
{
for (int i = 0; i < _сount; i++)
yield return _array[i];
}
public IEnumerator<T> GetEnumerator()
{
return Enumerate().GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator()
{
return Enumerate().GetEnumerator();
}
}
Этот список может только добавлять и изменять элементы, так же его можно создать на основе любой другой коллекции. Можно и далее его улучшеть, научить его удалять элементы, добавлять сразу по несколько элементов, и так далее. Я написал этот код только ради того, чтобы показать, что если самостояытельно делать "изменяемый" массив, то это может выглядеть как код, представленный выше.
Интерфейс IEnumerable<T> здесь для того, чтобы с этим списком можно было использовать цикл foreach и полезняшки из System.Linq. То есть, можно считать, что получилась более-менее полноценная изменяемая коллекция, которая не будет тормозить изменяя размер массива каждый раз при добавлении элемента.
Давайте потестируем, что получилось.
static void Main(string[] args)
{
MyList<string> list = new MyList<string>();
list.Add("Раз");
list.Add("Два");
list.Add("Три");
Console.WriteLine($"Количество элементов 'list': {list.Count}");
for (int i = 0; i < list.Count; i++)
Console.WriteLine(list[i]);
MyList<int> list2 = new MyList<int>();
for (int i = 0; i < 20; i++)
list2.Add(i);
Console.WriteLine($"Количество элементов 'list2': {list2.Count}");
Console.WriteLine(string.Join(" ", list2));
}
Вывод в консоль:
Количество элементов 'list': 3
Раз
Два
Три
Количество элементов 'list2': 20
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
Кажется, работает.