Passing a generic Array with unknow dimension

Hello, I want to create an extension method that go throuth all elements of any multidimentional generic array.
But I completely new to the generic concept. Is it possible to passing a generic array with unknow dimension as parameter throuth a function?

It’s all I have for the moment:

public static class ExtensionMethods
{
    public static void DebugArrayDimension<T>(T arrayUnknownDimension)
    {
        Debug.Log(arrayUnknownDimension.Rank); //Error
    }
}

Instead of using arrays, maybe try using ArrayLists. An ArrayList functions the same way as an array, but has some convenience methods and is dynamic in size. They’re also generic by design.

Thank for your replies but I 'm not really satisfied by them.

Maybe I didn’t understand them well or maybe I wasn’t clear enough in my question.

What I want is to merge this methods in one more generic:

    public static void Debug1DArrayDimension<T>(T[] array)
    {
        Debug.Log(array.Rank); // print 1
    }

    public static void Debug2DArrayDimension<T>(T[,] array)
    {
        Debug.Log(array.Rank); // print 2
    }

    public static void Debug3DArrayDimension<T>(T[,,] array)
    {
        Debug.Log(array.Rank); // print 3
    }

Creation of array whose component type is either a type parameter, a concrete parameterized type or a bounded wildcard parameterized type, is type-unsafe.

public T getArray(int size) {
T arr = new T; // Suppose this was allowed for the time being.
return arr;
}

The type of T is not known at runtime, the array created is actually an Object. So the above method at runtime will look like:

public Object getArray(int size) {
Object arr = new Object;
return arr;
}

Well, this doesn’t work with generics. They way generic code and generic type parameters work is that any code that involves variables of the given generic type can only access things that all possible type parameters have in common. Since you don’t have any constraint on your type parameter “T” it could be literally any type. you could pass an “int” , a string, an array or an object. The thing with generics is that the code is compiled at compile time and has to work consistently while the actual type is bound at runtime.

So a generic type parameter without constraints would only provide the things defined in System.Object which is just “ToString()”, “GetType()”, “GetHashCode()” and “Equals()”. So for generics to actually be useful you have to use a type constraint. The point of generics is to provide type safe code on similar objects. Though while different arrays are in deed similar they are not the same. Native arrays are implemented though actual IL opcode iistructions. The common base class System.Array is not a true base class. It’s not possible to use that pseudo-base-cass System.Array as generic constraint. The compiler won’t allow this. The Array base class is similar to the ValueType or Enum base class. It’s not a true base class.

However every native array type can be assigned to a variable of type System.Array. In the end you have to realize that multidimensional arrays do not really exist ^^. Every array is essentially just a chunk of memory and the elements are laid out linearly one after another. The multidimensional array support consists of special get and set methods that just handle the index mapping for you. Unfortunately if you have a multidimensional array you don’t get direct access to the actual 1d array. This is mainly due to the fact that how multidimensional arrays are implemented is an implementation details of the CLR which could even change. Though what you do get is a linear read-only access to all elements since every array implements the IEnumerable interface which gives you read access to all elements as a linear sequence. So the easiest way to “debug” / iterate through all elements of any kind of array is to use a method like this:

public void DebugArray(System.Array aArray) 
{ 
    foreach(object o in aArray)
    {
        Debug.Log(o.ToString());
    }
}

This just ignores the dimensions. If you want / need to know the actual indices you have to actually iterate through them:

public void DebugArray(System.Array aArray) 
{
    if (aArray == null || aArray.Length == 0)
        return;
    var indices = new int[aArray.Rank];
    var maxIndex = new int[aArray.Rank];
    for(int i = 0; i < maxIndex.Length; i++)
        maxIndex *= aArray.GetLength(i);*

bool done = false;
while (!done)
{
object val = aArray.GetValue(indices);
Debug.Log(“[”+indices.Aggregate(“”,(a,v)=>a+“,”+v.ToString())+"] "+ val.ToString());
for(int i = indices.Length-1; i >=0; i–)
{
if (++indices < maxIndex*)*
break;
else if (i > 0)
indices = 0;
else
done = true;
}
}
}
The while loop + the inner for loop allows to handle (almost) infinite nested for loops. The two int arrays hold the loop variable (indices) and the element count (maxIndex) for each dimension. The for loop does the incrementing of all variables and does handle the “carrying” between the dimensions as well as handling the exit condition once all elements have been processed.
Note: This method only works with arrays which have a starting index at 0. .NET allows arrays to have a lower bound different from 0. In that case the code would become a bit more complicated since we can’t simply use GetLength but we have to use GetLowerBound and GetUpperBound to get the min and max values and adjust the incrementing code accordingly. Though almost nobody uses them as they have a slight performance penalty and the C# language doesn’t have a direct syntax to create them. You can only create them through “Array.CreateInstance”. Anyways if you want to be on the safe side, here’s a version that works with multidimensional arrays of any rank and with any bounds:
public void DebugArray(System.Array aArray)
{
if (aArray == null || aArray.Length == 0)
return;
var indices = new int[aArray.Rank];
var minIndex = new int[aArray.Rank];
var maxIndex = new int[aArray.Rank];
for (int i = 0; i < maxIndex.Length; i++)
{
indices = minIndex = aArray.GetLowerBound(i);
maxIndex = aArray.GetUpperBound(i);
}
bool done = false;
while (!done)
{
object val = aArray.GetValue(indices);
Debug.Log(“[”+indices.Aggregate(“”,(a,v)=>a+“,”+v.ToString())+"] "+ val.ToString());
for(int i = indices.Length-1; i >=0; i–)
{
if (++indices <= maxIndex*)*
break;
else if (i > 0)
indices = minIndex*;*
else
done = true;
}
}
}
ps: Just to make it clear: The “Aggregate” extension method is a Linq extension. So you need a using System.Linq; at the top. It’s just a quick and dirty way to convert our indices array into a comma seperated string. If the leading comma bugs you, add a .SubString(1) right after the Aggregate call.