I have a method that takes a generic parameter T. Inter开发者_JAVA技巧nally, 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?
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.
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?
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.
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
}
精彩评论