Re: Динамическое создание делегатов через Reflection.Emit
От: desco США http://v2matveev.blogspot.com
Дата: 01.07.06 14:50
Оценка:
Здравствуйте, 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;
        }
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.