2

I have method like this:

public async Task<IEnumerable<DataResponse>> GetAsync() { ... }

I use reflection and I want to get the type "DataResponse", but I get type "Task<IEnumerable>"

    static void Main(string[] args)
    {
        var assemblies = GetAssemblies();
        IEnumerable<Type> controllers =
            assemblies.SelectMany(a => a.GetTypes().Where(t => t.IsSubclassOf(typeof(ControllerBase))));

        foreach (var controller in controllers)
        {
            var methods = controller.GetMethods();
            foreach (var methodInfo in methods)
            {
                var returnType = methodInfo.ReturnType;
            }
        }
    }

How do I get types excluding standard types ("task", "IEnumerable", e.t.c)?

Fedya Savchuk
  • 147
  • 2
  • 2
  • 13

1 Answers1

0

Task<IEnumerable> is a generic type whose one generic argument IEnumerable which is in turn a generic type whose generic argument is DataResponse

So methodInfo.ReturnType.GetGenericTypeArguments()[0].GetGenericTypeArguments()[0] would do the trick for this particular method.

Of course this wouldn't solve all cases.

A more generic way

 // Pass all types you want to strip here, for example, List<>, IList<>, Task<>, etc.
 returnType = StripTypes(returnType, typeof(Task<>), typeof(IEnumerable<>), typeof(List<>));

static Type StripTypes(Type type, params Type[] typesToStrip)
{
    if (!type.IsGenericType)
    {
        return type;
    }
    var definition = type.GetGenericTypeDefinition();
    if (Array.IndexOf(typesToStrip, definition) >= 0)
    {
        return StripTypes(type.GetGenericArguments()[0], typesToStrip);
    }
    return type;
}
Sherif Elmetainy
  • 4,034
  • 1
  • 13
  • 22