Reputation: 1346
I have a method that takes a generic parameter T. Internally, to decide what other methods to call, I need to know (without constraining it) if that parameter is a List or just something.
How do I do that?
I've been using
var isList = typeof(T).Name.ToLower().Contains("list`1");
but that feels like a dirty approach. What's cleaner?
Upvotes: 5
Views: 306
Reputation: 27515
var type = typeof(T);
bool isList = type.IsGenericType && type.GetGenericTypeDefinition() == typeof(List<>);
If you don't need an exact match for List, you might also just check if typeof(IList).IsAssignableFrom(typeof(T))
, which many list-like collections implement.
If you want to support T being equal to IList<T2>
directly (so the type parameter T is an interface), then you need to check for that separately (GetGenericTypeDefinition()
could also return typeof(IList<>)
).
If you want to support any type T that inherits from any IList<>
, then you have to get a bit more creative. You have to enumerate all interfaces, check if they are generic (as above) and then check if the generic type of the interface is IList<>
. Also, because the GetInterfaces() call on Type only returns the top-level interfaces, you need to navigate through all of the interfaces implemented by each interface (recursively), to check those as well. Ugly, I know.
Upvotes: 11
Reputation: 5132
If you are looking for any built in collection, you would check for IEnumerable. That way you do not need to worry about the type parameter. However this poses a problem because string implements IEnumerable. Therefore you would need some code like this:
if (typeof(T) is string) {
} else if (typeof(T) is IEnumerable) {
} else { // its something else
}
Upvotes: 0
Reputation: 124790
Well, you can always just use typeof(T)
and the is
keyword, but I would take another look at your design.
Your approach is really defeating the purpose of a generic method. If you have to check the type of the generic argument, well, your method isn't generic. Generics are great for scenarios where you don't care what the underlying type is. If you care then the method shouldn't be generic, it should be overloaded (probably). How abut telling us what you are actually trying to accomplish here so that we can give more helpful responses?
Upvotes: 2
Reputation: 445
Check to see if it implements the interface IEnumerable.
bool isList = T is IEnumerable;
This will also return true if T is a Stack, Array, or other such things, but I think it'll be sufficient for your purposes.
Upvotes: 0