tags:

views:

235

answers:

8

Hi,

I have class that has a property that is of type string[].

I need to create another array item, do I have to reset the size and copy all the previous items over?

+1  A: 

Yes. Arrays have fixed size.

From C# specification:

12.2 Array creation
...
When an array instance is created, the rank and length of each dimension are established and then remain constant for the entire lifetime of the instance. In other words, it is not possible to change the rank of an existing array instance, nor is it possible to resize its dimensions.

You may also take a look at blog post from Eric Lippert Arrays considered somewhat harmful

Dzmitry Huba
+12  A: 

You can use Array.Resize which will preserve the contents of the array.

e.g.

var array = myClass.SomeArrayProperty;
Array.Resize(ref array, newSize);
myClass.SomeArrayProperty = array;

You need to use a temporary variable because properties cannot be used as ref arguments.

Greg Beech
This, internally, basically does a reallocate + copy, though, so it's still a requirement.
Reed Copsey
sample code? The class property is string[]
mrblah
Yes of course; arrays have a fixed size. However the question was "do *I* have to" and the answer is no as this functionality is built in.
Greg Beech
+5  A: 

Yes, if you want to be able to dynamically append items use a List.

Although it's a best practice to not expose List as a property, so use IList<string> or IEnumerable<String> instead.

Ryu
+6  A: 

If it's your class, you should probably change the property to use an IList<string>, ICollection<string> or IEnumerable<string>, depending on how you anticipate this property will be used. Then, whichever of those you choose to return from the function, try using a List<string> in the type itself.

Joel Coehoorn
A: 

I would prefer copying the string[] to List<string>, perform all the manipulations, then .ToArray() to produce the resulting string[].

csharptest.net
Wow, that was harsh, and no reasoning why it was such a horrible practice?
csharptest.net
I'm interested to know as well. Perhaps start a new question describing your answer and ask why it's bad?
Daniel Schaffer
Fixt with an upvote. It's a decent solution if the property is a string array that he doesn't own and can't control.
Mike Hofer
A: 

Do you control the class? If so, consider using List<string> internally instead.

(And while you're at it, consider using IList<string> in your public API instead of string[].)

LukeH
+3  A: 

I would use a list if possible. It's a lot easier to manage. Obviously this depends on if it's your class and your able to chance this without any problems.

List<string> myList = new List<string>();
            myList.Add("item");
            myList.Remove("item");

If your having to use arrays then use

Array.Resize

Andi
A: 

It is easier to work with List<T>, but if you don't control the property this isn't an option. Note that this is seen commonly in soap-generated proxies, but IIRC there is a command-line switch you can use if you prefer lists to arrays.

Note that if you are doing this regularly, an extension method may be helpful:

public static T[] Append<T>(this T[] arr, T item) {
    Array.Resize(ref arr, arr == null ? 1 : (arr.Length + 1));
    arr[arr.Length-1] = item;
    return arr;
}

Which you can then use for your property:

obj.SomeProp = obj.SomeProp.Append(someValue);

(note this works even if obj.SomeProp is null, creating an array of length 1)

If it were a field/variable, then a simple ref argument might also work:

public static void Append<T>(ref T[] arr, T item) {
    Array.Resize(ref arr, arr == null ? 1 : (arr.Length + 1));
    arr[arr.Length-1] = item;
}
Marc Gravell