Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
298 views
in Technique[技术] by (71.8m points)

reflection - F# equivalent of the C# typeof(IEnumerable<>)

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.

question from:https://stackoverflow.com/questions/2480250/f-equivalent-of-the-c-sharp-typeofienumerable

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Answer

0 votes
by (71.8m points)

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>))

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome to OStack Knowledge Sharing Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...