I'm aware of this question, and it's follow-up, and also this one, but I can't put them together in a way which will help me do what I want to do:
I have a generic type, and I want to check that T is a struct
OR if it implements IEnumerable<T2>
, then I'd like to check that T2 is a struct
.
So far, I've got to here ('scuse the scrappy code, this is experimental):
private class TestClass<T>
{
public TestClass()
{
Type type = typeof(T);
//(detecting T == IEnumerable<something> ommitted for clarity)
Type enumerableType = type.GetInterfaces()
.Where(t => t.IsGenericType)
.Select(t => t.GetGenericTypeDefinition())
.Where(t => t == typeof(IEnumerable<>))
.FirstOrDefault();
if(enumerableType != null)
{
Type enumeratedType = type.GetGenericArguments().First();
if(!enumeratedType.IsValueType) //throw etc...
}
}
}
The problem I have is that enumerableType
is IEnumerable<>
, so the enumeratedType
comes out as T
, not whatever I've passed in (eg. new TestClass<int[]>()
).
Your problem is that you've selected away the type that has all the data in favor of it's erased generic type template.
Try:
Type enumerableType = type.GetInterfaces()
.Where(t => t.IsGenericType)
.Where(t => t.GetGenericTypeDefinition() == typeof(IEnumerable<>))
.Select(t => t.GetGenericArguments()[0])
.FirstOrDefault();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With