Есть ли способ рассматривать статический массив C # как ArrayList? - PullRequest
2 голосов
/ 12 марта 2009

У меня есть код, который использует массивы и, к сожалению, я не могу изменить их типы. Если бы я мог, я бы использовал ArrayLists или что-то похожее, чтобы делать то, что мне нужно, но я не могу. По сути, я ищу лучший подход для добавления и удаления объектов из статического массива. Для добавления элемента в массив на лету я должен создать новый массив, который на один элемент больше старого массива, скопировать элементы из старого массива в новый массив и добавить новый элемент. как то так ...

public partial class dataStruct 
{
    private myObject[] myStaticArray;
};

private void AddItemToMyArray()
{
    int oldLength = dataStruct.myStaticArray.Length;
    myObject[] newMyObjectArray = new myObject[oldLength + 1];
    for (int i = 0; i < oldLength; i++)
       newMyObjectArray [i] = dataStruct.myStaticArray[i];

    dataStruct.myStaticArray[oldLength] = new myObject();
    dataStruct.myStaticArray = newMyObjectArray;
}

для удаления элемента, я делаю то же самое, только я создаю новый массив, который на один элемент меньше. это кажется действительно неэффективным. Кто-нибудь может предложить лучший подход, если он есть? или какие-то другие мысли?

Заранее благодарим за помощь!

Ответы [ 6 ]

6 голосов
/ 12 марта 2009

Нет - массивы всегда имеют фиксированный размер. Вы не можете добавлять / удалять записи из них.

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

Одна вещь, которая сделает ваш код более простым (но, вероятно, не более эффективным), это использование Array.Resize . Он не изменяет размер существующего массива 1017 *, но возвращает новый массив с поверхностной копией старого содержимого в том размере, который вы запрашиваете. Копирование может быть немного быстрее, чем с ручным циклом, но основная причина неэффективности все еще там.

3 голосов
/ 12 марта 2009

к сожалению, я не могу изменить их типы

Почему бы и нет? Единственный разумный ответ - у вас есть API, который вы должны использовать с функциями, которые их возвращают или требуют их в качестве параметров. В этом случае используйте List<T> и вызывайте его методы .ToArray() или .AddRange(), если необходимо.

3 голосов
/ 12 марта 2009

Почему вы хотите использовать массив здесь? Переключитесь на List<T> или (если вам нужно эффективное удаление / вставка из середины) a LinkedList<T>.

Я не уверен, что вы имеете в виду «статический» в том смысле, в каком я это имею в виду - вы можете уточнить?

Для информации, вы можете использовать Array.Resize(ref myArray, newSize), но это не правильный ответ для частых изменений.

2 голосов
/ 12 марта 2009

Судя по звукам, вы не можете изменить структуру данных, поэтому приходится иметь дело с массивами.

Единственная вещь, по которой вы можете получить помощь, это то, что вы можете избежать цикла и сделать Array.copy

int oldLength = dataStruct.myStaticArray.Length;
myObject[] newMyObjectArray = new myObject[oldLength + 1];
Array.copy(dataStruct.myStaticArray, newMyObjectArray, oldLength);

dataStruct.myStaticArray[oldLength] = new myObject();
dataStruct.myStaticArray = newMyObjectArray;

РЕДАКТИРОВАТЬ На самом деле это может работать:

int oldLength = dataStruct.myStaticArray.Length;
Array.Resize(dataStruct.myStaticArray, oldLength+1);
0 голосов
/ 12 марта 2009

Все, что вы можете сделать, чтобы сделать массив более похожим на ArrayList или List<T>, просто заставит вас в конечном итоге повторно реализовать часть (или все) этих классов. Лучше всего использовать встроенные классы, как указано в других ответах.

0 голосов
/ 12 марта 2009

Вы в основном пишете свой собственный Список, но менее эффективным способом.

Список выполняет то, что вы описываете, но с одной большой разницей в производительности.

Когда он перераспределяет свой внутренний массив, он не просто добавляет один новый элемент, он добавляет их блок. Таким образом, будущие добавления не всегда требуют перераспределения. Это «емкость» списка - и почему емкость списка всегда> = размер списка.

Если вы должны это сделать, я бы порекомендовал сделать что-то подобное. Тем не менее, переключение на Список будет гораздо лучшим вариантом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...