I have a piece of code where I need to figure out if a given type implements IEnumerable<T>
(I don't care about the T)
I've tried (t:System.Type
in case you wonder)
let interfaces = t.GetInterfaces() let enumerbale = interfaces.Any(fun t -> t.GetGenericTypeDefinition() = typeof<IEnumerable<>> )
however that won't compile (the compile doesn't like the <>). I then tried
let interfaces = t.GetInterfaces() let enumerbale = interfaces.Any(fun t -> t.GetGenericTypeDefinition() = typeof<IEnumerable<'a>> )
but get's a warning that 'a is constraint to obj. I Don't want to figure out if IEnumerable<obj>
is implemented but IEnumerabl<>
.
Any one know's the solution and btw feel free to comment on the code above as well.
This should work:
typedefof<System.IEnumerable<_>>
EDIT
As Tomas notes, there's nothing special about the _
wildcard here; F# infers that the type obj
is the most general applicable type in this context, so this is the same as using typedefof<System.IEnumerable<obj>>
. In some cases the way this works can be a bit of a hindrance, though. For instance, if you define an interface type I<'a when 'a :> I<'a>> = interface end
, then you can't use typedefof<I<_>>
, because I<obj>
doesn't satisfy the generic constraint and F# can't infer another more appropriate type. This can happen even without recursive constraints (e.g. type I<'a when 'a : struct and 'a :> System.ICloneable> = interface end
. This is in contrast to C#'s approach, which works perfectly fine in the analogous cases.
As to your code itself, I think you'll want to make some other changes, too, such as ensuring that the interface is generic before calling GetGenericTypeDefinition
. Here's how I'd write the test function:
(fun t -> t.IsGenericType && (t.GetGenericTypeDefinition() = typedefof<_ seq>))
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