How can I create an instance of an arbitrary Array type at runtime?

I'm trying to deserialize an array of an type unknown at compile time. At runtime I've discovered the type, but I don't know how to create an instance.

Something like:

Object o = Activator.CreateInstance(type);

which doesn't work because there is no parameterless constructor, Array doesn't seem to have any constructor.


Use Array.CreateInstance.


You can use one of Array's CreateInstance overloads e.g.:-

object o = Array.CreateInstance(type, 10);

Quite an old post, but while answering a new question, though of posting a related example of creating a multi-dimensional array.

Assuming the type (elementType) as int and a two-dimensional array for example.

var size = new[] { 2, 3 };                
var arr = Array.CreateInstance(typeof(int), size);

When it's two dimensional, for example, it can be populated as

var value = 1;
for (int i = 0; i < size[0]; i++)
    for (int j = 0; j < size[1]; j++)
        arr.SetValue(value++, new[] { i, j });
//arr = [ [ 1, 2, 3 ], [ 4, 5, 6 ] ]

An alternative is to use expression trees for performance. For e.g. if you have array type, type you could do

var ctor = type.GetConstructors().First(); // or find suitable constructor
var argsExpr = ctor.GetParameters().Select(x => Expression.Constant(0)); 
var func = Expression.Lambda<Func<object>>(Expression.New(ctor, argsExpr)).Compile();

This just returns an empty array. Probably not very useful. MSDN states GetConstructors doesn't guarantee any order, so you might need a logic to find right constructor with right parameters to instantiate with correct size. For e.g. you could do:

static Func<object> ArrayCreateInstance(Type type, params int[] bounds) // can be generic too
{
    var ctor = type
        .GetConstructors()
        .OrderBy(x => x.GetParameters().Length) // find constructor with least parameters
        .First();

    var argsExpr = bounds.Select(x => Expression.Constant(x)); // set size
    return Expression.Lambda<Func<object>>(Expression.New(ctor, argsExpr)).Compile();
}

The same can be achieved much easier with Expression.NewArrayBounds instead of Expression.New, more over it works if all you got is array element type, not array type itself. Demo:

static Func<object> ArrayCreateInstance(Type type, params int[] bounds) // can be generic too
{
    var argsExpr = bounds.Select(x => Expression.Constant(x)); // set size
    var newExpr = Expression.NewArrayBounds(type.GetElementType(), argsExpr);
    return Expression.Lambda<Func<object>>(newExpr).Compile();
}

// this exercise is pointless if you dont save the compiled delegate, but for demo purpose:

x = string[] {...
y = ArrayCreateInstance(x.GetType(), 10)(); // you get 1-d array with size 10

x = string[,,] {...
y = ArrayCreateInstance(x.GetType(), 10, 2, 3)(); // you get 3-d array like string[10, 2, 3]

x = string[][] {...
y = ArrayCreateInstance(x.GetType(), 10)(); // you get jagged array like string[10][]

Just change type.GetElementType() to simply type if what you're passing is element type itself.