5

I am attempting to resize a 3D array in C#.

The VB6 code reads:

ReDim Combos(ProductNum, 4, 3)

Since I cannot use Array.Resize for a 3D array, is there another way for me to do this function in C#?

I have already declared the array as a 3D array:

int[ , , ] Combos;

But I am having trouble resizing it. Any ideas?

Ry-
  • 218,210
  • 55
  • 464
  • 476
eric_13
  • 383
  • 1
  • 8
  • 22
  • I have attempted to use Array.Copy but was unsure of how it would work as well. – eric_13 Jul 05 '12 at 16:19
  • see http://stackoverflow.com/questions/6539571/how-to-resize-multidimensional-2d-array-in-c – ken2k Jul 05 '12 at 16:24
  • 2
    Is there a reason why you're using an Array instead of a, say, List? – RobIII Jul 05 '12 at 16:24
  • Yes, I am doing a conversion from vb6 to C# and therefore want to keep it as an array. – eric_13 Jul 05 '12 at 16:27
  • 2
    @user1482934 Part of the process of converting from VB6 to C# *should* include updating collections to their more appropriate collection types available now. A verbatim conversion will just lead to a mess – Reed Copsey Jul 05 '12 at 16:31

3 Answers3

4

There is no way to directly redimension a multidimensional array in .NET. I would recommend allocating a new array, and then copying the values into it using Array.Copy.

That being said, depending on what you're doing, you may want to consider using a different collection type, as well. There are more options in .NET than VB6 in terms of collections, so many cases which used multidimensional arrays are better suited towards other collection types, especially if they are going to be resized.

Ry-
  • 218,210
  • 55
  • 464
  • 476
Reed Copsey
  • 554,122
  • 78
  • 1,158
  • 1,373
  • "There is no way to directly redimension an array in .NET": what about Array.Resize()? http://msdn.microsoft.com/en-us/library/1ffy6686 – Asik Jul 05 '12 at 16:27
  • 1
    @Dr_Asik It doesn't work with multidimensional arrays - I edited to be more clear – Reed Copsey Jul 05 '12 at 16:30
  • Array.Resize() internally allocates new array, copies the elements and returns that new array (note that by ref parameter). – Dusan Jul 05 '12 at 16:30
  • In order to use Array.Copy would I create a new array,NewCombo and then use Array.Copy like so - Array.Copy(Combo,NewCombo,Combo.ProductNum) and then do the same for the other values or can i do all 3 in one? Thanks again. – eric_13 Jul 05 '12 at 16:32
  • @user1482934 You may be able to use one copy operation, but you'll likely need multiple. It depends on *how* you're resizing the array. See Array.Copy for a description of how the memory is arranged within the multi-dimensional array (which is why I linked to the version which lets you specify positions and # of elements, etc) – Reed Copsey Jul 05 '12 at 16:35
  • @user1482934 In general, I'd **very strongly recommend** considering a different collection type that would handle this for you, though, as it gets fairly complicated to handle cleanly. – Reed Copsey Jul 05 '12 at 16:35
4

Even for the one-dimensional array, in C#, the array resizing works by copying elements into new re-sized array.

If you need to re-size array often, collections would be much better solution.

If you still want to resize array, here is the code:

T[,,] ResizeArray<T>(T[,,] original, int xSize, int ySize, int zSize)
{
    var newArray = new T[xSize, ySize, zSize];
    var xMin = Math.Min(xSize, original.GetLength(0));
    var yMin = Math.Min(ySize, original.GetLength(1));
    var zMin = Math.Min(zSize, original.GetLength(2));
    for (var x = 0; x < xMin; x++)
        for (var y = 0; y < yMin; y++)
            for (var z = 0; z < zMin; z++)
                newArray[x, y, z] = original[x, y, z];
    return newArray;
}
Dusan
  • 5,000
  • 6
  • 41
  • 58
1

Code:

        public int[,,] ReDimension(int[,,] OldArray,int arr1stDimLength,int arr2ndDimLength,int arr3rdDimLength)
     {
        // declare a larger array
         int[,,] NewArray = new int[arr1stDimLength,arr2ndDimLength,arr3rdDimLength];

        // determine if we are shrinking or enlarging
        const int FirstDimension = 0;
        const int SecondDimension = 1;
        const int ThirdDimension = 2;
        int xMax = 0;
        int yMax = 0;
        int zMax = 0;
         // determine if we are shrinking or enlarging columns
         if (OldArray.GetUpperBound(FirstDimension) < (arr1stDimLength - 1))
             xMax = OldArray.GetUpperBound(FirstDimension) + 1;
        else
             xMax = arr1stDimLength;

         // determine if we are shrinking or enlarging rows
         if (OldArray.GetUpperBound(SecondDimension) < (arr2ndDimLength - 1))
             yMax = OldArray.GetUpperBound(SecondDimension) + 1;
         else
             yMax = arr2ndDimLength;

         // determine if we are shrinking or enlarging depth
         if (OldArray.GetUpperBound(ThirdDimension) < (arr3rdDimLength - 1))
             zMax = OldArray.GetUpperBound(ThirdDimension) + 1;
        else
            zMax = arr3rdDimLength;

         // place values of old array into new array
         for(int z = 0; z < zMax; z++)
         {
             for(int x = 0; x < xMax; x++)
             {
                 for(int y = 0; y < yMax; y++)
                 {
                     NewArray[x, y, z] = OldArray[x, y, z];
                     Console.Write("[{0}]", NewArray[x, y, z]);
                 }
                 Console.Write("\n");
             }
             Console.Write("\n\n");
         }

         return NewArray;
    }

Taken from: http://www.codeproject.com/Articles/2503/Redhotglue-C-ArrayObject

Tested in C# (VS 2008) with a console app:

    static void Main(string[] args)
    {
        int[, ,] combos = new int[1,2,3];
        Console.WriteLine("Combos size: {0}",combos.Length.ToString());
        combos = ReDimension(combos, 5, 5, 5);
        Console.WriteLine("New Combos size: {0}", combos.Length.ToString());
        Console.ReadKey();
    }

Seems to work fine.

dcreight
  • 641
  • 6
  • 18