views:

170

answers:

6

I have code that uses Arrays and, unfortunately, I can't change their types. If I could, I'd use ArrayLists or something simliar to do what I need to do, but I can't. Basically, I'm looking for the best approach to adding and removing objects from a static array. For adding an item to the array on the fly, i have to create a new array that is one element bigger than the old array, copy the items from the old array into the new array, and add the new item. something like this...

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;
}

for deleting an item, i do the same thing, only I create a new array that is one item smaller. this feels really inefficient. can anyone suggest a better approach, if there is one? or any other thoughts?

thanks in advance for all your help!

+3  A: 

Why do you want to use an array here? Switch to List<T>, or (if you need efficient removals/insertions from the middle) a LinkedList<T>.

I'm not sure if you are meaning "static" in the way I mean it - can you clarify?

For info, you can use Array.Resize(ref myArray, newSize), but that isn't the right answer for frequent changes.

Marc Gravell
To expand on this, since he's now complained that he can't, the List<T> class has a .ToArray() method you can call whenever you need to use an API that requires an array.
Joel Coehoorn
Since he's now "explained" that he can't. =P
+6  A: 

No - arrays are always a fixed size. You can't add/delete entries from them.

This is precisely the restriction that ArrayList and List<T> work around, effectively. They maintain an array internally, but that is usually larger than the logical size of the list. When you add an item to a List<T> it will populate the existing array if it can, or if there's not enough room it will create a new, larger array and copy the contents into it. This change is transparent to the caller though - you can still use the original reference, because it's a reference to the list and not to the underlying array.

One thing which will make your code simpler (but probably not more efficient) is to use Array.Resize. It doesn't resize the existing array, but returns a new array with a shallow copy of the old content, at the size you request. The copying may be a little bit faster than with a manual loop, but the main cause of inefficiency is still there.

Jon Skeet
A: 

You're basically writing your own List, but in a less efficient manner.

List does internally what you are describing, but with one big difference in regards to performance.

When it reallocates its internal array, it doesn't just add one new element, it adds a block of them. That way, future adds don't always require reallocation. This is the list's "Capacity" - and why the list capacity is always >= the list's size.

If you must do this, I'd recommend doing something similar. However, switching to List would be a much better option.

Reed Copsey
A: 

Anything that you can do to make an array more like an ArrayList or List<T> is just going to cause you to end up re-implementing part (or all) of those classes. Your best best is to use the built-in classes, as the other answers have stated.

Andy
+2  A: 

From the sounds of it you can't change the data structure so have to deal with arrays.

The only thing you can get help on really is that you can avoid the loop and do an 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;

EDIT Actually this might work:

int oldLength = dataStruct.myStaticArray.Length;
Array.Resize(dataStruct.myStaticArray, oldLength+1);
Tom
Just FYI - Array.Copy is actually often slower than the loop. In this case, it's boxing/unboxing internally on every copy, since you're copying ints. This was one of the advantages .net2 and generics brought in.
Reed Copsey
+3  A: 

unfortunately, I can't change their types

Why not? The only reasonable answer is that you have an API you must use with functions that return them or require them as parameters. In that case, use List<T> and call it's .ToArray() or .AddRange() methods as needed.

Joel Coehoorn