I can't find a way to do it for any generic type, but if you need to do it for a specific type, it is possible in some cases.
For instance, I have the following code to check if a type is a collection, and if it is, get the element type:
private static bool IsCollectionType(CodeType type, out CodeType elementType)
{
// string implements IEnumerable<char>, but we don't want to treat it as a collection
if (type.FullName == "System.String")
{
elementType = null;
return false;
}
var enumerable = type.Bases.OfType<CodeInterface>().FirstOrDefault(i => i.FullName.StartsWith("System.Collections.Generic.IEnumerable<"));
var method = enumerable?.Members.OfType<CodeFunction>().FirstOrDefault(m => m.Name == "GetEnumerator");
var enumerator = method?.Type.CodeType;
var current = enumerator?.Members.OfType<CodeProperty>().FirstOrDefault(m => m.Name == "Current");
if (current != null)
{
elementType = current.Type.CodeType;
return true;
}
elementType = null;
return false;
}
As you can see, I'm not directly looking at the generic type argument, but instead I look at the type of IEnumerable<T>.GetEnumerator().Current
. Of course, this requires specific knowledge about the type you're working with.