我的代码生成一个动态创建多维数组的方法,假设一个维度长度数组,但似乎JIT编译器甚至CLR都无法正确地从维度长度数组加载项目。
不是创建int[10, 10, 10]
数组,而是创建一个int[10, 10, 0]
数组。它似乎在OpCodes.Ldelem_I
出错了,但是,使用OpCodes.Ldelem, typeof(int)
代替工作。重现此行为,任何CPU设置是必需的,x86工作正常。调试和释放模式都会出现此问题。
这是一个错误吗?我无法判断这一点,因为我无法深入研究这一点。
class Program
{
static void Main(string[] args)
{
CreateMultidimensionalArrayCreator(typeof(int[, ,])).Invoke(new int[] { 10, 10, 10 }); ;
}
static Func<int[], Array> CreateMultidimensionalArrayCreator(Type type)
{
int rank = type.GetArrayRank();
DynamicMethod method = new DynamicMethod(String.Empty, typeof(Array), new Type[] { typeof(int[]) }, typeof(Program), false);
ILGenerator ilGen = method.GetILGenerator();
for (int i = 0; i < rank; i++)
{
// Load element from dimension lengths array
ilGen.Emit(OpCodes.Ldarg_0);
ilGen.Emit(OpCodes.Ldc_I4, i);
ilGen.Emit(OpCodes.Ldelem_I); // Somehow returns 0 for last element, however, OpCodes.Ldelem appears to work fine
// Duplicate element and write to console for diagnostics
ilGen.Emit(OpCodes.Dup);
ilGen.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(int) }));
}
// Get parameters for multidimensional array constructor
//
Type[] parameterTypes = new Type[rank];
for (int i = 0; i < rank; i++)
{
parameterTypes[i] = typeof(int);
}
ilGen.Emit(OpCodes.Newobj, type.GetConstructor(BindingFlags.Public | BindingFlags.Instance, null, parameterTypes, null));
ilGen.Emit(OpCodes.Ret);
return (Func<int[], Array>)method.CreateDelegate(typeof(Func<int[], Array>));
}
}
答案 0 :(得分:0)
替换行:
ilGen.Emit(OpCodes.Ldelem_I); // Somehow returns...
到行:
ilGen.Emit(OpCodes.Ldelem_I4); // Somehow returns 0 for last element....