Я создаю динамический тип с этим:Как мне вызвать функцию из переменной в классе, созданном с помощью Reflection.Emit?
AssemblyName assemblyName = new AssemblyName("LunarDynamicAssembly");
AssemblyBuilder _assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.Run);
ModuleBuilder _moduleBuilder = _assembly.DefineDynamicModule("DynamicModule", true);
TypeBuilder typeBuilder = _moduleBuilder.DefineType(original.Name + "Proxy", TypeAttributes.Public | TypeAttributes.Class, original, new Type[] { typeof(IProxy) });
// - This function only implements the IProxy interface and returns the private variable field.
FieldBuilder _interceptor = ImplementIProxy(typeBuilder);
ConstructorInfo _interceptorConstructor = typeof(Interceptor).GetConstructor(Type.EmptyTypes);
foreach (ConstructorInfo constructorInfo in original.GetConstructors())
{
//Omitting for brev.
//Recreating all the constructors and ensuring there's a line
//_interceptor = new Interceptor();
//in all of them.
}
foreach (PropertyInfo pInfo in original.GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
MethodInfo getMethod = pInfo.GetGetMethod();
MethodInfo setMethod = pInfo.GetSetMethod();
PropertyBuilder propertyBuilder = typeBuilder.DefineProperty(pInfo.Name, pInfo.Attributes, pInfo.PropertyType, null);
MethodAttributes attributes = MethodAttributes.Public | MethodAttributes.SpecialName | MethodAttributes.HideBySig | MethodAttributes.Virtual | MethodAttributes.Final | MethodAttributes.NewSlot;
MethodBuilder getBuilder = typeBuilder.DefineMethod(getMethod.Name, attributes, pInfo.PropertyType, null);
ILGenerator getIL = getBuilder.GetILGenerator();
// - Issues start here
getIL.Emit(OpCodes.Ldarg_0);
getIL.Emit(OpCodes.Ldloc, _interceptor);
getIL.Emit(OpCodes.Callvirt, typeof(Interceptor).GetMethod("InterceptingFunction"));
getIL.Emit(OpCodes.Stloc_0);
getIL.Emit(OpCodes.Ldloc_0);
getIL.Emit(OpCodes.Ret);
typeBuilder.DefineMethodOverride(getBuilder, getMethod);
}
InterceptingFunction
возвращает тот же тип, что и собственность. Я предполагаю, что мне не хватает того, как поставить «экземпляр» до того, как я вызову функцию, из того, что я проверил в ILDasm. Как я могу это сделать?
Исключение: Common Language Runtime обнаружил недействительную программу.
(Edit) Подробнее Ил код функции, которая делает то, что я пытаюсь создать (для возврата 20 части):
// Code size 20 (0x14)
.maxstack 1
.locals init ([0] int32 CS$1$0000)
IL_0000: nop
IL_0001: ldarg.0
IL_0002: ldfld class [Test]Test.DataAccess.Interceptor Tests.MyClass::_interceptor
IL_0007: callvirt instance void [Test]Test.DataAccess.Interceptor::InterceptingFunction()
IL_000c: nop
IL_000d: ldc.i4.s 20
IL_000f: stloc.0
IL_0010: br.s IL_0012
IL_0012: ldloc.0
IL_0013: ret
Поместите свой код в try catch и проверьте трассировку стека исключений. –
@ gp. Это значит, что InnerException отсутствует, а трассировка стека отображается в MyClassProxy.get_ClassID() в Tests.Program.Main (String [] args) в e: \ Projects \ Tests \ Program.cs: строка 19' – Danicco
IL-код показывает Тип возврата InterceptFunction недействителен. Я попробовал подобный образец и часть «instace» перед вызовом функции не проблема. Проверьте подпись InterceptFunction. Сохраните динамическую сборку, затем проверьте с помощью 'peverify' –