Im пытается создать прокси-класс из интерфейса. В методах я просто хочу собрать все аргументы в массиве объектов и перейти к известному методу. Таким образом, мне удалось заставить его работать без параметров и с возвращаемыми типами. Как только я пытаюсь создать свой массив, я получаю «Дополнительная информация: Common Language Runtime обнаружила недействительную программу». .. Не знаю, как отлаживать отсюда, и коды IL кажутся правильными (?).Reflection.Emit Внедрить интерфейс и создать массив IL
public class Program
{
static void Main(string[] args)
{
var v = CreateProxy<IFoo>();
v.DoSomething();
}
public static void TheMethod(object[] args)
{
}
public interface IFoo
{
void DoSomething();
}
public static T CreateProxy<T>()
{
var interfaceType = typeof(T);
AssemblyName assemblyName = new AssemblyName(string.Format("tmp_{0}", interfaceType.FullName));
string moduleName = string.Format("{0}.dll", assemblyName.Name);
string ns = interfaceType.Namespace;
if (!string.IsNullOrEmpty(ns))
ns += ".";
var assembly = AppDomain.CurrentDomain.DefineDynamicAssembly(assemblyName,AssemblyBuilderAccess.RunAndSave);
var module = assembly.DefineDynamicModule(moduleName, false);
var type = module.DefineType(String.Format("{0}Proxy_{1}", ns, interfaceType.Name), TypeAttributes.Class | TypeAttributes.AnsiClass |TypeAttributes.Sealed |TypeAttributes.NotPublic);
type.AddInterfaceImplementation(interfaceType);
//Constructor
var ctor = type.DefineConstructor(MethodAttributes.Public, CallingConventions.HasThis, new Type[] {});
var generator = ctor.GetILGenerator();
generator.Emit(OpCodes.Ret);
//Methods
foreach (var method in interfaceType.GetMethods())
{
var args = method.GetParameters();
var methodImpl = type.DefineMethod(method.Name, MethodAttributes.Public | MethodAttributes.Virtual, method.ReturnType, (from arg in args select arg.ParameterType).ToArray());
generator = methodImpl.GetILGenerator();
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ldc_I4_1);
generator.Emit(OpCodes.Newarr, typeof(object));
generator.Emit(OpCodes.Stloc_0);
generator.Emit(OpCodes.Ldloc_0);
generator.Emit(OpCodes.Call, typeof(Program).GetMethod(nameof(Program.TheMethod)));
generator.Emit(OpCodes.Nop);
generator.Emit(OpCodes.Ret);
}
return (T)Activator.CreateInstance(type.CreateType());
}
}
Метод im, пытающийся испустить, должен выглядеть следующим образом.
public void DoSomething()
{
object[] arr = new object[1];
Program.TheMethod(arr);
}
Что мне здесь не хватает?
Его статический? Нет необходимости в экземпляре? – Evelie