Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Unable to cast List<int[*]> to List<int[]> instantiated with reflection

I am instantiating a List<T> of single dimensional Int32 arrays by reflection. When I instantiate the list using:

Type typeInt = typeof(System.Int32);
Type typeIntArray = typeInt.MakeArrayType(1);
Type typeListGeneric = typeof(System.Collections.Generic.List<>);
Type typeList = typeListGeneric.MakeGenericType(new Type[] { typeIntArray, });

object instance = typeList.GetConstructor(Type.EmptyTypes).Invoke(null);

I see this strange behavior on the list itself:

Watch of the list instance as an object

If I interface with it through reflection it seems to behave normally, however if I try to cast it to its actual type:

List<int[]> list = (List<int[]>)instance;

I get this exception:

Unable to cast object of type 'System.Collections.Generic.List`1[System.Int32[*]]' to type 'System.Collections.Generic.List`1[System.Int32[]]'.

Any ideas what may be causing this or how to resolve it? I am working in visual studio 2010 express on .net 4.0.

like image 327
Einherjar Avatar asked Oct 06 '13 20:10

Einherjar


2 Answers

The problem is caused by the MakeArrayType function. The way you're using it you create a multidimensional array with one dimension, which is not the same as a one dimensional array (vector).

From the documentation:

The common language runtime makes a distinction between vectors (that is, one-dimensional arrays that are always zero-based) and multidimensional arrays. A vector, which always has only one dimension, is not the same as a multidimensional array that happens to have only one dimension. You cannot use this method overload to create a vector type; if rank is 1, this method overload returns a multidimensional array type that happens to have one dimension. Use the MakeArrayType() method overload to create vector types.

Change:

Type typeIntArray = typeInt.MakeArrayType(1);

to this:

Type typeIntArray = typeInt.MakeArrayType();

to create an ordinary one-dimensional vector.

like image 160
BartoszKP Avatar answered Oct 09 '22 18:10

BartoszKP


What MSDN says about MakeArrayType(int):

You cannot use this method overload to create a vector type; if rank is 1, this method overload returns a multidimensional array type that happens to have one dimension. Use the MakeArrayType() method overload to create vector types.

like image 30
JustAndrei Avatar answered Oct 09 '22 17:10

JustAndrei