Reputation: 5576
public class MyList : List<MyClass>
How can I get the type MyClass
through reflection if I have an object
that contains an instance of MyList
? The list can be empty, so I can't do something like myList[0].GetType()
.
p.s. I can't just stop using MyList
and directly use the generic List instead (the situation is a bit more complicated, and there are reasons for "hiding" the generic argument), so I can't pick up MyClass
through GetGenericArguments()
.
Upvotes: 2
Views: 802
Reputation: 17850
Is your class implements generic interfaces? you can use the following code:
Type argument = GetGenericArgument(typeof(MyList), typeof(IList<>));
//...
static Type GetGenericArgument(Type type, Type genericTypeDefinition) {
Type[] interfaces = type.GetInterfaces();
for(int i = 0; i < interfaces.Length; i++) {
if(!interfaces[i].IsGenericType) continue;
if(interfaces[i].GetGenericTypeDefinition() == genericTypeDefinition)
return interfaces[i].GetGenericArguments()[0];
}
return null;
}
Without interfaces you can try the following:
class A { }
class B { }
class G<T> { }
class G1<T> : G<A> { }
class G2 : G1<B> { }
//...
Type argument1 = GetGenericArgument(typeof(G2)); // B
Type argument2 = GetGenericArgument(typeof(G2),1 ); // A
//...
static Type GetGenericArgument(Type type, int level = 0) {
do {
if(type.IsGenericType && 0 == level--)
return type.GetGenericArguments()[0];
type = type.BaseType;
}
while(type != null);
return null;
}
Upvotes: 0
Reputation: 172646
var elementType = (
from iface in myList.GetType().GetInterfaces()
where iface.IsGenericType
where iface.GetGenericTypeDefinition() == typeof(IList<>)
select iface.GetGenericArguments()[0])
.Single();
I use IList<T>
instead of list. This is more generic. However, there is also the change of a type implementing multiple ILis<T>
versions (such as IList<string>
and IList<int>
).
Upvotes: 7
Reputation: 62504
MyList list = new MyList();
Type baseTypeGenericArgument = list.GetType().BaseType.GetGenericArguments()[0];
string argumentTypeName = baseTypeGenericArgument.GetType().FullName;
Upvotes: 0
Reputation: 3519
You can get the base type, which will be List<MyClass>
; from it you can get the generic type argument with GetGenericArguments.
Upvotes: 1