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