If I do something like this:
var a = new List<something>();
var b = new something();
a.Add(b);
var c = a[0].GetType();
C holds the type I want (which is "something"). How could you get the type of "something" without creating the list?
If I do something like this:
var a = new List<something>();
var b = new something();
a.Add(b);
var c = a[0].GetType();
C holds the type I want (which is "something"). How could you get the type of "something" without creating the list?
In this case, you can just say var c = typeof(something);
but in the general case you can use this:
Type c = a.GetType().GetGenericArguments()[0];
To be more specific, there are perhaps 4 different cases:
void func1(List<something> arg)
{
Type t = typeof(something);
}
void func2<T>(List<T> arg)
{
Type t = typeof(T);
}
void func3(object arg)
{
// assuming arg is a List<T>
Type t = arg.GetType().GetGenericArguments()[0];
}
void func4(object arg)
{
// assuming arg is an IList<T>
Type t;
// this assumes that arg implements exactly 1 IList<> interface;
// if not it throws an exception indicating that IList<> is ambiguous
t = arg.GetType().GetInterface(typeof(IList<>).Name).GetGenericArguments()[0];
// if you expect multiple instances of IList<>, it gets more complicated;
// we'll take just the first one we find
t = arg.GetType().GetInterfaces().Where(
i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IList<>))
.First().GetGenericArguments()[0];
}
If you're looking for the T
in IList<T>
it gets complicated because you can actually have a type declared like class FooBar: IList<Foo>, IList<Bar>
. This is why the last function gives a couple different possibilities. If you want an exception thrown in the case of an ambiguity, go with the first possibility. If you just want to pick any arbitrary one, go with the second. If you care about which one you get, you'll have to do a bit more coding to somehow choose which one best meets your needs.
Use the typeof
operator, e.g. typeof(T)
or typeof(something)
.