lundi 4 juillet 2016

GenericTypeDefinitionName from IEnumerable

NOTE: This question is about a technical aspect, and NOT about design decisions. Answering or commenting about a different design does NOT answer this question, since I'm only interested in the nature of the technical aspect of this specific question.

In C# 6.0 I have this method where I'm passing an IEnumerable<T>:

public void MyMethod(IEnumerable<object> list) { ... }

Let's say the caller calls it on an IEnumerable<MyClass>.
What I want is the class name of the generic type definition, I had this implementation of the method:

public void MyMethod(IEnumerable<object> list)
{
    ...
    var name =
        from abstraction in list.GetType().GetInterfaces()
        where abstraction.IsGenericType
        && abstraction.GetGenericTypeDefinition() == typeof(IEnumerable<>)
        from genericArgumentType in abstraction.GetGenericArguments()
        select genericArgumentType.Name;
    ...
}

Now in this case (inside the body of the method), this correctly returns the name of the class (e.g. a string "MyClass"). So I tried to refactor this into an open generic extension method like so:

public static string GetGenericTypeDefinitionName<T>(this IEnumerable<T> list)
{
    var name =
        from abstraction in list.GetType().GetInterfaces()
        where abstraction.IsGenericType
        && abstraction.GetGenericTypeDefinition() == typeof(IEnumerable<>)
        from genericArgumentType in abstraction.GetGenericArguments()
        select genericArgumentType.Name;

    return name.Single();
}

Which also works, but then I realized: 'Hey! Why not just return typeof(T).Name?'

Which turned out it returns the string "Object", while I expected the same result (e.g. "MyClass") as the previous implementation.

Is it even possible to get the expected type? It seems all information is lost when dealing with the open generic type T. Also why am I not getting the expected type? What are the technical details of this particular behavior for C#?





Aucun commentaire:

Enregistrer un commentaire