В настоящее время у меня есть следующий код, когда я запускаю его, я получаю код ошибки. Операция может дестабилизировать среду выполнения (этот мой обновленный код il соответствует символу, но он все еще не работает)
public static Func<IDataReader, Object> TestMethod<T>()
{
var method = new DynamicMethod("", typeof(Object), new[]
{
typeof ( IDataReader )
});
var il = method.GetILGenerator();
Label whileIf = il.DefineLabel();
Label whileStart = il.DefineLabel();
Label methodEnd = il.DefineLabel();
il.Emit(OpCodes.Newobj, typeof(List<string>).GetConstructor(new Type[0]));
il.Emit(OpCodes.Stloc_0);
il.Emit(OpCodes.Br_S, whileIf);
il.MarkLabel(whileStart);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Ldc_I4_0);
il.Emit(OpCodes.Callvirt, typeof(IDataRecord).GetMethod("GetString"));
il.Emit(OpCodes.Callvirt, typeof(List<string>).GetMethod("Add"));
il.MarkLabel(whileIf);
il.Emit(OpCodes.Ldarg_0);
il.Emit(OpCodes.Callvirt, typeof(IDataReader).GetMethod("Read"));
il.Emit(OpCodes.Brtrue_S, whileStart);
il.Emit(OpCodes.Ldloc_0);
il.Emit(OpCodes.Ret);
return (Func<IDataReader, Object>)method.CreateDelegate(typeof(Func<IDataReader, Object>));
}
Он был создан из этого кода:
public List<string> method(IDataReader dataReader)
{
var result = new List<string>();
while (dataReader.Read())
result.Add(dataReader.GetString(0));
return result;
}
Что генерирует следующий код IL:
IL_0000: nop
IL_0001: newobj System.Collections.Generic.List<System.String>..ctor
IL_0006: stloc.0 // result
IL_0007: br.s IL_0017
IL_0009: ldloc.0 // result
IL_000A: ldarg.1
IL_000B: ldc.i4.0
IL_000C: callvirt System.Data.IDataRecord.GetString
IL_0011: callvirt System.Collections.Generic.List<System.String>.Add
IL_0016: nop
IL_0017: ldarg.1
IL_0018: callvirt System.Data.IDataReader.Read
IL_001D: stloc.2 // CS$4$0001
IL_001E: ldloc.2 // CS$4$0001
IL_001F: brtrue.s IL_0009
IL_0021: ldloc.0 // result
IL_0022: stloc.1 // CS$1$0000
IL_0023: br.s IL_0025
IL_0025: ldloc.1 // CS$1$0000
IL_0026: ret
Я пишу этот код в IL, так как в конечном итоге я буду расширять код, который динамически создает этот код для заполнения типа из TArg. Извините, у меня нет больше информации, которую мне дает вся визуальная студия.
Это мой сигильский код, который работает и работает правильно:
var emiter = Emit<Func<IDataReader, List<String>>>.NewDynamicMethod("MyMethod");
var whileIf = emiter.DefineLabel("whileIf");
var whileStart = emiter.DefineLabel("whileStart");
emiter.DeclareLocal(typeof(List<string>), "0");
emiter.NewObject<List<String>>();
emiter.StoreLocal("0");
emiter.Branch(whileIf);
emiter.MarkLabel(whileStart);
emiter.LoadLocal("0");
emiter.LoadArgument(0);
emiter.LoadConstant(0);
emiter.CallVirtual(typeof(IDataRecord).GetMethod("GetString"));
emiter.CallVirtual(typeof(List<string>).GetMethod("Add"));
emiter.MarkLabel(whileIf);
emiter.LoadArgument(0);
emiter.CallVirtual(typeof(IDataReader).GetMethod("Read"));
emiter.BranchIfTrue(whileStart);
emiter.LoadLocal("0");
emiter.Return();
Func<IDataReader, List<string>> result = emiter.CreateDelegate();
Disassembler<Func<IDataReader, List<string>>>.Disassemble( result );
return result;
AssemblyBuilder
? Если вы используете это для создания своего метода, вы можете сохранить сборку на диск и запустить PEVerify для созданной сборки. Обычно это говорит вам, что не так. - person   schedule 28.11.2013