C# - Get the item type for a generic list
Solution 1:
You could use the Type.GetGenericArguments
method for this purpose.
List<Foo> myList = ...
Type myListElementType = myList.GetType().GetGenericArguments().Single();
Solution 2:
For a more robust approach:
public static Type GetListType(object someList)
{
if (someList == null)
throw new ArgumentNullException("someList");
var type = someList.GetType();
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(List<>))
throw new ArgumentException("Type must be List<>, but was " + type.FullName, "someList");
return type.GetGenericArguments()[0];
}
But if your variable is typed List<T>
then you can just use typeof(T)
. For example:
public static Type GetListType<T>(List<T> someList)
{
return typeof(T);
}
Note that you don't really even need the someList
parameter. This method is just an example for how you could use typeof
if you are already in a generic method. You only need to use the reflection approach if you don't have access to the T
token (the list is stored in a non-generic-typed variable, such as one typed IList
, object
, etc.).
Solution 3:
list.GetType().GetGenericArguments()[0]
Solution 4:
Here's another way which works for non-generic collections, too:
static Type GetItemType(Type collectionType)
{
return collectionType.GetMethod("get_Item").ReturnType;
}
That is, get the return type of foo[x]
, where foo
is of the specified type.
Examples:
// Generic type; prints System.Int32
Console.WriteLine(GetItemType(typeof(List<int>)));
// Non-generic type; prints System.String
Console.WriteLine(GetItemType(typeof(System.Collections.Specialized.StringCollection)));
The GetItemType
method above has a couple issues, though:
It throws a
NullReferenceException
if the type has no indexing operator.It throws an
AmbiguousMatchException
if the type has multiple overloads for the indexing operator (e.g.this[string]
andthis[int]
).
Here is a more refined version:
public static Type GetItemType(this Type collectionType)
{
var types =
(from method in collectionType.GetMethods()
where method.Name == "get_Item"
select method.ReturnType
).Distinct().ToArray();
if (types.Length == 0)
return null;
if (types.Length != 1)
throw new Exception(string.Format("{0} has multiple item types", collectionType.FullName));
return types[0];
}