89

Is it possible to change an array size after declaration? If not, is there any alternative to arrays?
I do not want to create an array with a size of 1000, but I do not know the size of the array when I'm creating it.

20 Answers 20

105

You can use Array.Resize(), documented in MSDN.

But yeah, I agree with Corey, if you need a dynamically sized data structure, we have Lists for that.

Important: Array.Resize() doesn't resize the array (the method name is misleading), it creates a new array and only replaces the reference you passed to the method.

An example:

var array1 = new byte[10];
var array2 = array1;
Array.Resize<byte>(ref array1, 20);

// Now:
// array1.Length is 20
// array2.Length is 10
// Two different arrays.
Sign up to request clarification or add additional context in comments.

10 Comments

If Array.Resize() is just once at the beginning (and not multiple times during the program), is that more suitable than a List?
List<T> uses an Array behind the scenes, so there are very few reasons to use an Array in C#. Lists can be initialized to a suitable size using this constructor: msdn.microsoft.com/en-us/library/dw8e0z9z.aspx. But yes, if your heart is set on Arrays, it's better to resize them as infrequently as possible.
I thought List<T> uses a linked list or some data structure behind. So it uses array after all.
Be carefull, Array.Resize does not preserve your reference. Instead, it creates a new array of the required size.
List<Int> is using Array.Resize under the covers. It uses a generally (though not universally) optimal algorithm under the covers, wherein it doubles the size of the array each time that it grows it. Unless you are working on high performance realtime systems (high-speed trading or mechanical control systems for example) you should use List<Int> as it will be "good enough" and is more maintainable.
|
68

No, try using a strongly typed List instead.

For example:

Instead of using

int[] myArray = new int[2];
myArray[0] = 1;
myArray[1] = 2;

You could do this:

List<int> myList = new List<int>();
myList.Add(1);
myList.Add(2);

Lists use arrays to store the data so you get the speed benefit of arrays with the convenience of a LinkedList by being able to add and remove items without worrying about having to manually change its size.

This doesn't mean an array's size (in this instance, a List) isn't changed though - hence the emphasis on the word manually.

As soon as your array hits its predefined size, the JIT will allocate a new array on the heap that is twice the size and copy your existing array across.

1 Comment

Yes by this way: string[] arr1 = new string[]{}; Array.Resize(ref arr1, 7);
15

Yes, it is possible to resize an array. For example:

int[] arr = new int[5];
// increase size to 10
Array.Resize(ref arr, 10);
// decrease size to 3
Array.Resize(ref arr, 3);

If you create an array with CreateInstance() method, the Resize() method is not working. For example:

// create an integer array with size of 5
var arr = Array.CreateInstance(typeof(int), 5);
// this not work
Array.Resize(ref arr, 10);

The array size is not dynamic, even we can resize it. If you want a dynamic array, I think we can use generic List instead.

var list = new List<int>();
// add any item to the list
list.Add(5);
list.Add(8);
list.Add(12);
// we can remove it easily as well
list.Remove(5);
foreach(var item in list)
{
  Console.WriteLine(item);
}

Comments

12

You can use Array.Resize() in .net 3.5 and higher. This method allocates a new array with the specified size, copies elements from the old array to the new one, and then replaces the old array with the new one. (So you will need the memory available for both arrays as this probably uses Array.Copy under the covers)

Comments

6

In C#, arrays cannot be resized dynamically.

  • One approach is to use System.Collections.ArrayList instead of a native array.

  • Another (faster) solution is to re-allocate the array with a different size and to copy the contents of the old array to the new array.

    The generic function resizeArray (below) can be used to do that.

    public static System.Array ResizeArray (System.Array oldArray, int newSize)  
        {
          int oldSize = oldArray.Length;
          System.Type elementType = oldArray.GetType().GetElementType();
          System.Array newArray = System.Array.CreateInstance(elementType,newSize);
    
          int preserveLength = System.Math.Min(oldSize,newSize);
    
          if (preserveLength > 0)
          System.Array.Copy (oldArray,newArray,preserveLength);
    
         return newArray; 
      }  
    
     public static void Main ()  
           {
            int[] a = {1,2,3};
            a = (int[])ResizeArray(a,5);
            a[3] = 4;
            a[4] = 5;
    
            for (int i=0; i<a.Length; i++)
                  System.Console.WriteLine (a[i]); 
            }
    

Comments

5

Use System.Collections.Generic.List

Comments

5

Use a List<T> instead. For instance, instead of an array of ints

private int[] _myIntegers = new int[1000];

use

private List<int> _myIntegers = new List<int>();

later

_myIntegers.Add(1);

Comments

5

Used this approach for array of bytes:

Initially:

byte[] bytes = new byte[0];

Whenever required (Need to provide original length for extending):

Array.Resize<byte>(ref bytes, bytes.Length + requiredSize);

Reset:

Array.Resize<byte>(ref bytes, 0);

Typed List Method

Initially:

List<byte> bytes = new List<byte>();

Whenever required:

bytes.AddRange(new byte[length]);

Release/Clear:

bytes.Clear()

Comments

3

In C#, Array.Resize is the simplest method to resize any array to new size, e.g.:

Array.Resize<LinkButton>(ref area, size);

Here, i want to resize the array size of LinkButton array:

<LinkButton> = specifies the array type
ref area = ref is a keyword and 'area' is the array name
size = new size array

Comments

2
    private void HandleResizeArray()
    {
        int[] aa = new int[2];
        aa[0] = 0;
        aa[1] = 1;

        aa = MyResizeArray(aa);
        aa = MyResizeArray(aa);
    }

    private int[] MyResizeArray(int[] aa)
    {
        Array.Resize(ref aa, aa.GetUpperBound(0) + 2);
        aa[aa.GetUpperBound(0)] = aa.GetUpperBound(0);
        return aa;
    }

1 Comment

What do you do by doing UpperBound?
2

If you really need to get it back into an array I find it easiest to convert the array to a list, expand the list then convert it back to an array.

        string[] myArray = new string[1] {"Element One"};
        // Convert it to a list
        List<string> resizeList = myArray.ToList();
        // Add some elements
        resizeList.Add("Element Two");
        // Back to an array
        myArray = resizeList.ToArray();
        // myArray has grown to two elements.

Comments

1

Use a List (where T is any type or Object) when you want to add/remove data, since resizing arrays is expensive. You can read more about Arrays considered somewhat harmful whereas a List can be added to New records can be appended to the end. It adjusts its size as needed.

A List can be initalized in following ways

Using collection initializer.

List<string> list1 = new List<string>()
{
    "carrot",
    "fox",
    "explorer"
};

Using var keyword with collection initializer.

var list2 = new List<string>()
{
    "carrot",
    "fox",
    "explorer"
};

Using new array as parameter.

string[] array = { "carrot", "fox", "explorer" };
List<string> list3 = new List<string>(array);

Using capacity in constructor and assign.

List<string> list4 = new List<string>(3);
list4.Add(null); // Add empty references. (Not Recommended)
list4.Add(null);
list4.Add(null);
list4[0] = "carrot"; // Assign those references.
list4[1] = "fox";
list4[2] = "explorer";

Using Add method for each element.

List<string> list5 = new List<string>();
list5.Add("carrot");
list5.Add("fox");
list5.Add("explorer");

Thus for an Object List you can allocate and assign the properties of objects inline with the List initialization. Object initializers and collection initializers share similar syntax.

class Test
{
    public int A { get; set; }
    public string B { get; set; }
}

Initialize list with collection initializer.

List<Test> list1 = new List<Test>()
{
    new Test(){ A = 1, B = "Jessica"},
    new Test(){ A = 2, B = "Mandy"}
};

Initialize list with new objects.

List<Test> list2 = new List<Test>();
list2.Add(new Test() { A = 3, B = "Sarah" });
list2.Add(new Test() { A = 4, B = "Melanie" });

Comments

0

This worked well for me to create a dynamic array from a class array.

var s = 0;
var songWriters = new SongWriterDetails[1];
foreach (var contributor in Contributors)
{
    Array.Resize(ref songWriters, s++);
    songWriters[s] = new SongWriterDetails();
    songWriters[s].DisplayName = contributor.Name;
    songWriters[s].PartyId = contributor.Id;
    s++;
}

Comments

0

I tried out the Answer here in Linqpad and I see that the new items added to the resized Array is set to the default of the type.

int?[] originalArray = [1, 2, 3, 4, 5]; 
Array.Resize(ref originalArry, 10); //array now can hold fifteen items 

If we have an array of int?, the "empty" items added after resizing will get the default value of int? , which is NULL.

While an int array will set the same kind of elements after array resize to 0.

enter image description here

Comments

0

Probably not the answer people are looking for here, but this is what I needed when I searched for this. I needed to set the length of an array to something less than its capacity, and this is what worked for me. This is undefined behavior by all intents and purposes and should only be used if you know what you're doing.

public static unsafe void SetLengthUnsafe<T>(this T[] anArray, int aLength) where T : unmanaged
    {
        UnityEngine.Debug.Assert(anArray != null);
        fixed (void* arrayPtr = anArray)
        {
            const int LENGTH_BYTE_OFFSET = -8; //offset to length location
            int* intPtr = (int*)((byte*)arrayPtr + LENGTH_BYTE_OFFSET);
            intPtr[0] = aLength;
        }
        UnityEngine.Debug.Assert(anArray.Length == aLength, "The length of the array is different from the desired value, the LENGTH_BYTE_OFFSET has the wrong value.");
    }

Comments

-1

Use a generic List (System.Collections.Generic.List).

Comments

-1

In case you cannot use Array.Reset (the variable is not local) then Concat & ToArray helps:

anObject.anArray.Concat(new string[] { newArrayItem }).ToArray();

Comments

-1

I was looking for a way to increment the length of my array in a simple guessing game using while loops. The array was initialised with a length of 1. I used 'i' (initialised at 0) to record the number of guesses in the current round of the loop. Line 2 displays the lowest score in the array. After incrementing the array position for the next round, I used Array.Resize() to extend the length of the array by i + 1. This way, the array length extends with each iteration of the loop.

arr[i] = guesses; 
Console.WriteLine("Best Score: {0}", arr.Min()); 
i++; 
Array.Resize(ref arr, i + 1); 

Comments

-1
static void Resize(ref int[] Arr, int k)
{
    int[] newArray = new int[k];
    for (int i = 0; i < k; i++)
        newArray[i]=arr[i];            
    Arr=newArray;
}

1 Comment

Thank you for your interest in contributing to the Stack Overflow community. This question already has quite a few answers—including one that has been extensively validated by the community. Are you certain your approach hasn’t been given previously? If so, it would be useful to explain how your approach is different, under what circumstances your approach might be preferred, and/or why you think the previous answers aren’t sufficient. Can you kindly edit your answer to offer an explanation?
-1

I'm going to give a very different answer. Yes and you don't need lists or Array.Resize!! Example:

int[] arr = className.MethodName(arguments); \\ has size in ex. 10
arr = className.MethodName(newArguments); \\ now has a different size

your class methods can update the array size, no problem. In the code above replace the class name and method name and arguments accordingly.

1 Comment

This is reassigning the value of arr to something else, not actualy resizing the underlying array. the old array still exists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.