Гость
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить тип generic-ограничения / 18 сообщений из 18, страница 1 из 1
31.10.2020, 00:28
    #40013617
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Код: c#
1.
public void Foo<T>(T arg) where T : Bar {}


Как через Reflection получить TypeInfo Bar?
...
Рейтинг: 0 / 0
31.10.2020, 00:42
    #40013618
Shocker.Pro
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Код: c#
1.
typeof(Bar).GetMethod("Foo").GetGenericArguments().First().BaseType


за последнее свойство не уверен в правильности применения, но в данном случае оно typeof(Bar)
...
Рейтинг: 0 / 0
31.10.2020, 00:45
    #40013619
fkthis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Ну гуглится же моментально: https://stackoverflow.com/questions/5432822/reflection-over-type-constraints . Или тебя гугл сразу на скуль редиректит?
...
Рейтинг: 0 / 0
31.10.2020, 11:08
    #40013661
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
fkthis
Ну гуглится же моментально: https://stackoverflow.com/questions/5432822/reflection-over-type-constraints . Или тебя гугл сразу на скуль редиректит?
Все остальное нагуглилось, а вот именно это - нет. Бывает.
...
Рейтинг: 0 / 0
31.10.2020, 11:35
    #40013665
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Задача усложняется.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
public TResult Foo<TArgument, TResult>(TArgument arg) 
where TArgument : Bar1 
where TResult : Bar2 
{}

        public static async Task<object> InvokeAsync(this MethodInfo @this, object obj, params object[] parameters)
        {
            dynamic awaitable = @this.Invoke(obj, parameters);
            await awaitable;
            return awaitable.GetAwaiter().GetResult();
        }

var result = Task.Run(async () => await _method.InvokeAsync(_api, _request)).Result;


Итог:

Внутреннее исключение 1:
InvalidOperationException: Операции позднего связывания не могут быть выполнены для типов или методов, для которых значение ContainsGenericParameters является true.

Как-нибудь можно это обойти?
...
Рейтинг: 0 / 0
31.10.2020, 12:39
    #40013673
fkthis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Antonariy
Задача усложняется.

Ты откуда MethodInfo берешь?

Потому что вот так вот:
Код: c#
1.
2.
3.
4.
List<int> list = new();
var addMethod = list.GetType().GetMethod("Add");
addMethod?.Invoke(list, new object[] { 42 });
list.Should().BeEquivalentTo(new object[] { 42 });


все работает.
...
Рейтинг: 0 / 0
31.10.2020, 13:23
    #40013682
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Я тупанул, в качестве obj передал тип, а не экземпляр типа.

Однако, результат все равно тот же самый.
...
Рейтинг: 0 / 0
31.10.2020, 16:18
    #40013737
fkthis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Antonariy
Я тупанул, в качестве obj передал тип, а не экземпляр типа.

Однако, результат все равно тот же самый.

Я-таки еще раз вопрошаю - как ты получаешь MethodInfo?

Потому что у меня очень сильное, почти на уровне уверенности подозрение, что у тебя там что-то типа:
Код: c#
1.
var addMethod = typeof(List<>).GetMethod("Add");


вместо
Код: c#
1.
var addMethod = typeof(List<int>).GetMethod("Add");
...
Рейтинг: 0 / 0
31.10.2020, 21:10
    #40013789
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Мимо.

Я получаю класс из assembly по имени но у меня там не класс<тип>, а просто класс, не generic. Но у него generic-методы указанного выше вида.
...
Рейтинг: 0 / 0
31.10.2020, 21:13
    #40013790
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
fkthis
Код: c#
1.
var addMethod = typeof(List<int>).GetMethod("Add");

С таким-то кодом и reflection не нужно, все на этапе компиляции известно.
...
Рейтинг: 0 / 0
31.10.2020, 21:16
    #40013791
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Вот так я всё получаю, если сильно интересно:

Код: c#
1.
2.
            var apiType = typeof(BaseAdapter).Assembly.GetTypes().FirstOrDefault(v => v.Name == apiName);
            var method = apiType.GetMethods().FirstOrDefault(v => v.Name == methodName);

Но это ничем не поможет.
...
Рейтинг: 0 / 0
31.10.2020, 21:19
    #40013792
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
У List.Add, к слову, аргумент не generic, поэтому работает.
...
Рейтинг: 0 / 0
31.10.2020, 21:44
    #40013801
fkthis
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Antonariy
У List.Add, к слову, аргумент не generic, поэтому работает.

Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
public class Foo
{
    public void Bar<T>() => Console.WriteLine("Hello, " + typeof(T)); // Hello, System.Int32
}

internal class Program
{
    static void Main(string[] args)
    {
        var type = typeof(Foo);
        var genMethodInfo = type.GetMethod("Bar");

        // тут важно вот это:
        var methodInfo = genMethodInfo?.MakeGenericMethod(typeof(int));

        var foo = new Foo();
        methodInfo?.Invoke(foo, default);
    }
}


Идея понятна?

Ты когда ищешь MethodInfo по имени, то получаешь Generic Definition метода. А чтобы получить метод который можно вызвать тебе нужно для него сделать MakeGenericMethod с нужным типом (типами) данных.
...
Рейтинг: 0 / 0
01.11.2020, 00:19
    #40013850
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
fkthis
Идея понятна?
Вполне, спасибо. Пробовать бубу завтра.
...
Рейтинг: 0 / 0
01.11.2020, 00:41
    #40013855
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Antonariy,

А какая задача? Может через экспрешены можно решить?
...
Рейтинг: 0 / 0
01.11.2020, 10:48
    #40013893
fkthat
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
hVostt
Может через экспрешены можно решить?

Expressions vs Reflection это, обычно, только для оптимизации. Если у тебя Late Binding и известны тольько имена типов/методов в виде строковых переменных, то reflection все равно будет нужен, чтобы построить этот expression. От expression толк в том, что потом уже не надо при каждом вызове делать медленную рефлексию. В доекспрессионные времена для этого использовался Emit
...
Рейтинг: 0 / 0
01.11.2020, 12:30
    #40013909
Antonariy
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
Всё получилось.

hVostt
Antonariy,

А какая задача? Может через экспрешены можно решить?
Нужно из VBA выполнить произвольный метод net-сборки и вернуть результат.
...
Рейтинг: 0 / 0
01.11.2020, 18:18
    #40014003
hVostt
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Получить тип generic-ограничения
fkthat
Expressions vs Reflection это, обычно, только для оптимизации.


Ну дык о чём и речь :)
Экспрешены компилятся в рантайме, а дальше работают как обычные код, плюс какой-никакой тайпчекинг на уровне компиляции.

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


fkthat
Если у тебя Late Binding и известны тольько имена типов/методов в виде строковых переменных, то reflection все равно будет нужен, чтобы построить этот expression.


Всё верно, но только один раз :)


fkthat
В доекспрессионные времена для этого использовался Emit


Да и сейчас в некоторых задачах может иметь смысл :)
...
Рейтинг: 0 / 0
Форумы / WinForms, .Net Framework [игнор отключен] [закрыт для гостей] / Получить тип generic-ограничения / 18 сообщений из 18, страница 1 из 1
Целевая тема:
Создать новую тему:
Автор:
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]