Здравствуйте, nikov, Вы писали:
N>Возникла необходимость создать класс делегата с неизвестной заранее сигнатурой через Reflection.Emit. Уже приходилось раньше "обычные" классы так создавать, пользовался TypeBuilder'ом. Специальный механизм для делегатов поискал — не нашел. Неужто нужно "ручками" от System.MulticastDelegate наследоваться?
Взято из примера к
этой статье
public Type CreateCustomDelegate(MethodInfo targetMethod)
{
AssemblyName assembly;
AssemblyBuilder assemblyBuilder;
ModuleBuilder modbuilder;
TypeBuilder typeBuilder;
MethodBuilder methodBuilder;
assembly = new AssemblyName();
assembly.Version = new Version(1, 0, 0, 0);
assembly.Name = "ReflectionEmitDelegateTest";
assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.RunAndSave);
modbuilder = assemblyBuilder.DefineDynamicModule("MyModule", "mydelegatetest.exe", true);
// Create a delegate that has the same signature as the method we would like to hook up to
typeBuilder = modbuilder.DefineType("MyDelegateType", TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(System.MulticastDelegate));
ConstructorBuilder constructorBuilder = typeBuilder.DefineConstructor(MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(object), typeof(int) });
constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
// Grab the parameters of the method
ParameterInfo[] parameters = targetMethod.GetParameters();
Type[] paramTypes = new Type[parameters.Length];
for (int i = 0; i < parameters.Length; i++)
{
paramTypes[i] = parameters[i].ParameterType;
}
// Define the Invoke method for the delegate
methodBuilder = typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, targetMethod.ReturnType, paramTypes);
methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
// bake it!
Type t = typeBuilder.CreateType();
// assemblyBuilder.Save("mydelegatetest.exe"); // useful for testing
return t;
}