Неожиданный результат с type.GenericTypeArguments

avatar
Piercarlo
9 августа 2021 в 07:08
144
0
0

с отражением я успешно получаю список методов контроллера.

чтобы получить аргументы возвращаемого типа метода, я использую *.GenericTypeArguments следующим образом:

Some MethodInfo x.GenericTypeArguments.Select(a => a.Name);

При таком методе:

public async Task<ApiResult> SomeMethod();

я получаю хороший результат: "ApiResult"

Но когда возвращаемый тип имеет список вроде:

public async Task<List<string>> SomeMethod();

Я получаю -> Task,List,System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String] вместо Задача,Список,Строка

то же для

public async Task<Dictionary<string,string>> SomeMethod();

ожидаемая задача,словарь,строка,строка

получено Task,Dictionary,System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String]

here the exact code I use:

            Assembly asm = Assembly.GetExecutingAssembly();

            var controllerMethodlist = asm.GetTypes()
                    .Where(type => typeof(ControllerBase).IsAssignableFrom(type))
                    .SelectMany(type => type.GetMethods(BindingFlags.Instance | BindingFlags.DeclaredOnly | BindingFlags.Public))
                    .Where(m => !m.GetCustomAttributes(typeof(CompilerGeneratedAttribute), true).Any())
                    .Select(x => new
                    {
                        Controller = x.DeclaringType.Name,
                        Action = x.Name + "(" + String.Join(",", x.GetParameters().Select(p => p.Name)) + ")",
                        ReturnType = x.ReturnType.Name.LastIndexOf('`') == -1 ? x.ReturnType.Name : (x.ReturnType.Name.Substring(0, x.ReturnType.Name.LastIndexOf('`')) + "<" +
                        String.Join(",", x.ReturnType.GenericTypeArguments.Select(a => a.Name.LastIndexOf('`') == -1 ? a.Name : a.Name.Substring(0, a.Name.LastIndexOf('`')) +
                        (a.GenericTypeArguments.Count() > 0 ? "<" + String.Join(",", a.GenericTypeArguments.Select(b => b.Name.LastIndexOf('`') == -1 ? b.Name : b.Name.Substring(0, b.Name.LastIndexOf('`')) +
                        (b.GenericTypeArguments.Count() > 0 ? "<" + String.Join(",", b.GenericTypeArguments.Select(c => c.Name.LastIndexOf('`') == -1 ? c.Name : c.Name.Substring(0, c.Name.LastIndexOf('`'))) + ">") : ""))) + ">" : ""))) + ">")
                        ,
                        Attributes = String.Join(",", x.GetCustomAttributes().Select(a => a.GetType().Name.Replace("Attribute", "") + "|" +
                        (
                            a.GetType() == typeof(HttpGetAttribute) ? ((HttpGetAttribute)a).Template :
                            a.GetType() == typeof(HttpPostAttribute) ? ((HttpPostAttribute)a).Template :
                            a.GetType() == typeof(HttpDeleteAttribute) ? ((HttpDeleteAttribute)a).Template :
                            a.GetType() == typeof(HttpPutAttribute) ? ((HttpPutAttribute)a).Template :
                            a.GetType() == typeof(CrudControllerAuthAttribute) ? ((CrudControllerAuthAttribute)a).CrudAuth.ToString() :
                            "*"
                        )))
                    })
                    .OrderBy(x => x.Controller).ThenBy(x => x.Action).ToList();

Проблема в свойстве "ReturnType":

У меня есть следующие методы:

public async Task<IActionResult> ConfirmEmail(parameters) 

и как ResultType я получаю правильное значение

Task<IActionResult> 

Но следующим методом:

public async Task<ApiResultT<Dictionary<string,string>>> GetCsvDictionaryForTemplate(CsvBase64) 

в качестве ResultType я получаю

`Task<ApiResultT<Dictionary<System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String]>>>` 

вместо

Task<ApiResultT<Dictionary<string,string>>>

или следующим методом:

public async Task<ApiResultT<List<CsvClassesDto>>> GetCsvClasses()

Я получаю:

Task<ApiResultT<List<System.Linq.Enumerable+SelectArrayIterator`2[System.Type,System.String]>>>

Вместо:

Task<ApiResultT<List<CsvClassesDto>>>

Итак, у меня возникает проблема, когда тип представляет собой список или словарь, поэтому Enumerable.

Надеюсь, я понял

Спасибо за помощь

Пьеркарло

Источник
Sweeper
9 августа 2021 в 07:54
1

Пожалуйста, покажите минимальный воспроизводимый пример. В классе MethodInfo нет свойства с именем GenericTypeArguments.

Jimi
9 августа 2021 в 07:56
0

Можете ли вы опубликовать свой фактический код вместо этого: Some MethodInfo x.GenericTypeArguments.Select(a => a.Name);. Непонятно, как вы читаете аргументы универсального типа вложенных (не буквально) универсальных типов, которые определяют возвращаемый тип этих методов. -- Поскольку вы должны прочитать все аргументы каждого типа, пока IsGenericType = true, возможно, в процедуре что-то не так.

Ответы (0)