Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.86/7: Рейтинг темы: голосов - 7, средняя оценка - 4.86
 Аватар для netBool
325 / 304 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
.NET 4.x

Как получить тип несуществующего делегата?

06.05.2018, 11:51. Показов 1453. Ответов 5
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Странный вопрос получился в сабже.

Но собственно примерно такая задача и стоит. Мне нужно или как-то получить тип делегата, которого еще нет (т.е. создать тип динамически по заданным параметрам) или как-то создать динамически сам делегат, а потом получить его тип

Весь мой поиск упирается в какую-то стену. Пробовал через Reflection, но ModuleBuilder.DefineType возвращает по умолчанию класс, а не делегат

PS: В общем, если выше по тексту я как-то сложно изъяснился, то надо получить, например, тип такого делегата:

C#
1
2
3
delegate void MyFunc1(System.Windows.Forms.TreeView a)
//...
Type td = typeof(MyFunc1);
но динамически, рантайм

Добавлено через 19 минут
PPS: или если нельзя, то может как-то можно получить тип делегата на основе функции в MethodInfo?
0
Лучшие ответы (1)
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
06.05.2018, 11:51
Ответы с готовыми решениями:

Разница лямбда выражения, делегата (\анонимного делегата), методом (\анонимных методов)
Всё просто: В чём отличия: лямбд, делегатов, анонимных делегатов, методов, анонимных методов? У меня в проге сучилась такая...

Получить экземпляр делегата с использованием черной магии
Есть Generic делегат. Есть поле класса, типа этого делегата. Нужно с помощью рефлексии засунуть функцию соответствующей сигнатуры в это...

Отличие делегата от делегата с лямбда-выражением
Народ чем отличается Invoke(new Action(() => button2.IsEnabled = true)); от Invoke(new Action(delegate(){ button2.IsEnabled = true;...

5
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
06.05.2018, 12:18
Что нибудь типа
C#
1
2
var types = new Type[] { typeof(System.Windows.Forms.TreeView), typeof(void) };
var delType = Expression.GetDelegateType(types); // вернет тип Action<System.Windows.Forms.TreeView>
не подойдет?

Зачем это вообще понадобилось?
1
 Аватар для netBool
325 / 304 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
06.05.2018, 13:01  [ТС]
Цитата Сообщение от Someone007 Посмотреть сообщение
Что нибудь типа
Почти то, но не совсем.

Я пытаюсь получить указатель на функцию через GetFunctionPointerForDelegate. Засада в том, что мне не подходят Action<> и Func<>, т.к. они генерики, т.е. нужно как-то создать самый обычный пользовательский делегат на основе сигнатуры, переданной из MethodInfo
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
06.05.2018, 14:08
Лучший ответ Сообщение было отмечено netBool как решение

Решение

Цитата Сообщение от netBool Посмотреть сообщение
нужно как-то создать самый обычный пользовательский делегат на основе сигнатуры, переданной из MethodInfo
Ок.
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
    class DynamicDelegateCreator
    {
        AssemblyName assembly;
        AssemblyBuilder assemblyBuilder;
        ModuleBuilder modBuilder;
 
        public DynamicDelegateCreator()
        {
            assembly = new AssemblyName();
            assembly.Version = new Version(1, 0, 0, 0);
            assembly.Name = "DynamicDelegateCreator";
 
            assemblyBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(assembly, AssemblyBuilderAccess.Run);
 
            modBuilder = assemblyBuilder.DefineDynamicModule("MyModule");
        }
 
        public Delegate CreateDelegate(string name, object owner, MethodInfo targetMethod)
        {
            TypeBuilder typeBuilder = modBuilder.DefineType(name, 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(System.IntPtr) });
            constructorBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
 
            ParameterInfo[] parameters = targetMethod.GetParameters();
 
            Type[] paramTypes = new Type[parameters.Length];
 
            for (int i = 0; i < parameters.Length; i++)
                paramTypes[i] = parameters[i].ParameterType;
 
            MethodBuilder methodBuilder = typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, targetMethod.ReturnType, paramTypes);
 
            methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
 
            Type[] paramTypes2 = new Type[parameters.Length + 2];
 
            for (int i = 0; i < parameters.Length; i++)
                paramTypes2[i] = parameters[i].ParameterType;
 
            paramTypes2[parameters.Length] = typeof(AsyncCallback);
            paramTypes2[parameters.Length + 1] = typeof(object);
 
            methodBuilder = typeBuilder.DefineMethod("BeginInvoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, typeof(IAsyncResult), paramTypes2);
            methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
 
            Type[] paramTypes3 = new Type[] { typeof(IAsyncResult) };
 
            methodBuilder = typeBuilder.DefineMethod("EndInvoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, targetMethod.ReturnType, paramTypes3);
            methodBuilder.SetImplementationFlags(MethodImplAttributes.Runtime | MethodImplAttributes.Managed);
 
            Type delType = typeBuilder.CreateType();
 
            return Delegate.CreateDelegate(delType, owner, targetMethod);
        }
    }
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
    class TestClass
    {
        public TestClass()
        {
            DynamicDelegateCreator delCreator = new DynamicDelegateCreator();
 
            MethodInfo targetMethod = this.GetType().GetMethod("TestMethod", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
 
            Delegate del = delCreator.CreateDelegate("TestMethodDelegate", this, targetMethod);
 
            del.DynamicInvoke(new System.Windows.Forms.TreeView());
 
            var ptr = Marshal.GetFunctionPointerForDelegate(del);
 
            Console.WriteLine(ptr);
 
 
            MethodInfo targetMethod2 = this.GetType().GetMethod("TestMethod2", BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
 
            Delegate del2 = delCreator.CreateDelegate("TestMethod2Delegate", null, targetMethod2);
 
            del2.DynamicInvoke(new System.Windows.Forms.TreeView());
 
            var ptr2 = Marshal.GetFunctionPointerForDelegate(del2);
 
            Console.WriteLine(ptr2);
        }
 
        void TestMethod(System.Windows.Forms.TreeView a)
        {
            Console.WriteLine(a);
        }
 
        static void TestMethod2(System.Windows.Forms.TreeView a)
        {
            Console.WriteLine(a);
        }
    }
0
 Аватар для netBool
325 / 304 / 173
Регистрация: 16.11.2010
Сообщений: 1,069
Записей в блоге: 9
06.05.2018, 18:58  [ТС]
Someone007, спасибо! Честно говоря, если б не ваш ответ, я бы наверное отказался от этой затеи

Все заработало
Я проштудировал каждую строчку этого кода. Но так и не понял до конца, что он делает

Получается здесь
C#
1
            TypeBuilder typeBuilder = modBuilder.DefineType(name, TypeAttributes.Class | TypeAttributes.Public | TypeAttributes.Sealed | TypeAttributes.AnsiClass | TypeAttributes.AutoClass, typeof(System.MulticastDelegate));
Мы создаем новый класс, наследуемый от MulticastDelegate... Я бы долго до этого шел...

Далее
C#
1
typeBuilder.DefineConstructor(MethodAttributes.RTSpecialName | MethodAttributes.HideBySig | MethodAttributes.Public, CallingConventions.Standard, new Type[] { typeof(object), typeof(System.IntPtr) })
Создаем конструктор с входящими параметрами object и IntPtr. Тоже не понял, почему ( в принципе работает и без параметров вроде)

Но самое главное!
C#
1
MethodBuilder methodBuilder = typeBuilder.DefineMethod("Invoke", MethodAttributes.Public | MethodAttributes.HideBySig | MethodAttributes.NewSlot | MethodAttributes.Virtual, targetMethod.ReturnType, paramTypes);
Почему-то метод должен называться именно "Invoke")) С другими именами выдает ошибку

Просто вопрос из любопытства, это информация с какого-то иностранного ресурса или личные наработки?
0
Эксперт .NET
6691 / 4102 / 1607
Регистрация: 09.05.2015
Сообщений: 9,575
06.05.2018, 19:30
Цитата Сообщение от netBool Посмотреть сообщение
Просто вопрос из любопытства, это информация с какого-то иностранного ресурса или личные наработки?
Это я нагуглил, вот тут оригинал, блог за 2004 год...

Цитата Сообщение от netBool Посмотреть сообщение
Почему-то метод должен называться именно "Invoke"
Потому что у делегата такой метод должен быть? И еще BeginInvoke и EndInvoke для асинхронных вызовов (добавил их в код выше).
1
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
06.05.2018, 19:30
Помогаю со студенческими работами здесь

Как отключить отображение несуществующего монитора?
Ну и еще один странный вопрос: У меня ноутбук, на нем две видеокарты: HD 3000 и Radeon 7690 MX. Так вот, после установки Linux...

Как получить тип файла?
Можно ли средствами АСП установить тип файла (content type) если сам файл хранится в базе, но также в базе хранится имя файла (т.е. можно...

Необходимо получить тип элемента и с помощью CType или DirectCast изменить его тип
Всем привет! Подскажите, пожалуйста, есть ли вариант решения данной проблемы: Необходимо получить тип элемента и с помощью CType или...

Как получить тип поля из dll?
Всем привет! Мне необходимо получить нестатическое поле, но для этого нужно создать Instance, а для него нужен тип (класс) поля, в котором...

Как получить тип свойства (рефлексия)
Например у меня есть несколько классов class A { public B _bclass { get { return new B(); } } public C...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
6
Ответ Создать тему
Новые блоги и статьи
Вывод данных через динамический список в справочнике
Maks 01.04.2026
Реализация из решения ниже выполнена на примере нетипового справочника "Спецтехника" разработанного в конфигурации КА2. Задача: вывести данные из ТЧ нетипового документа. . .
Функция заполнения текстового поля в реквизите формы документа
Maks 01.04.2026
Алгоритм из решения ниже реализован на нетиповом документе "ВыдачаОборудованияНаСпецтехнику" разработанного в конфигурации КА2, в дополнении к предыдущему решению. На форме документа создается. . .
К слову об оптимизации
kumehtar 01.04.2026
Вспоминаю начало 2000-х, университет, когда я писал на Delphi. Тогда среди программистов на форумах активно обсуждали аккуратную работу с памятью: нужно было следить за переменными, вовремя. . .
Идея фильтра интернета (сервер = слой+фильтр).
Hrethgir 31.03.2026
Суть идеи заключается в том, чтобы запустить свой сервер, о чём я если честно мечтал давно и давно приобрёл книгу как это сделать. Но не было причин его запускать. Очумелые учёные напечатали на. . .
Модель здравосоХранения 6. ESG-повестка и устойчивое развитие; углублённый анализ кадрового бренда
anaschu 31.03.2026
В прикрепленном документе раздумья о том, как можно поменять модель в будущем
10 пpимет, которые всегда сбываются
Maks 31.03.2026
1. Чтобы, наконец, пришла маршрутка, надо закурить. Если сигарета последняя, маршрутка придет еще до второй затяжки даже вопреки расписанию. 2. Нaдоели зима и снег? Не надо переезжать. Достаточно. . .
Перемещение выделенных строк ТЧ из одного документа в другой
Maks 31.03.2026
Реализация из решения ниже выполнена на примере нетипового документа "ВыдачаОборудованияНаСпецтехнику" с единственной табличной частью "ОборудованиеИКомплектующие" разработанного в конфигурации КА2. . . .
Functional First Web Framework Suave
DevAlt 30.03.2026
Sauve. IO Апнулись до NET10. Из зависимостей один пакет, работает одинаково хорошо как в режиме проекта так и в интерактивном режиме. из сложностей - чисто функциональный подход. Решил. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru