25 people like it.

Create generic IEnumerable from non-generic

Depends on Castle Dynamic Proxy 2. Returns an IEnumerable from a System.Type and a System.Collections.IEnumerable. It is a hack I wrote simply because I couldn't find anything in the framework to do this.

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
19: 
20: 
21: 
module Seq =
    let private proxyGen = Castle.DynamicProxy.ProxyGenerator ()
    
    let cast2 (t : System.Type) (sq : System.Collections.IEnumerable) =
        let t1 = (typedefof<seq<_>>).MakeGenericType [| t |]
        let t2 = (typedefof<System.Collections.Generic.IEnumerator<_>>).MakeGenericType [| t |]
        proxyGen.CreateInterfaceProxyWithoutTarget (t1,
            { new IInterceptor with
                member self.Intercept (inv : IInvocation) =
                    let enum = sq.GetEnumerator ()
                    inv.ReturnValue <-
                        proxyGen.CreateInterfaceProxyWithoutTarget (t2,
                            { new IInterceptor with
                                member self.Intercept (inv : IInvocation) =
                                    match inv.Method.Name with
                                    | "MoveNext" -> inv.ReturnValue <- enum.MoveNext ()
                                    | "Reset" -> enum.Reset ()
                                    | "get_Current" -> inv.ReturnValue <- enum.Current
                                    | _ -> failwith "inconceivable"
                            })
            })
module Seq

from Microsoft.FSharp.Collections
val private proxyGen : obj

Full name: Script.Seq.proxyGen
val cast2 : t:System.Type -> sq:System.Collections.IEnumerable -> 'a

Full name: Script.Seq.cast2
val t : System.Type
namespace System
type Type =
  inherit MemberInfo
  member Assembly : Assembly
  member AssemblyQualifiedName : string
  member Attributes : TypeAttributes
  member BaseType : Type
  member ContainsGenericParameters : bool
  member DeclaringMethod : MethodBase
  member DeclaringType : Type
  member Equals : o:obj -> bool + 1 overload
  member FindInterfaces : filter:TypeFilter * filterCriteria:obj -> Type[]
  member FindMembers : memberType:MemberTypes * bindingAttr:BindingFlags * filter:MemberFilter * filterCriteria:obj -> MemberInfo[]
  ...

Full name: System.Type
val sq : System.Collections.IEnumerable
namespace System.Collections
type IEnumerable =
  member GetEnumerator : unit -> IEnumerator

Full name: System.Collections.IEnumerable
val t1 : System.Type
val typedefof<'T> : System.Type

Full name: Microsoft.FSharp.Core.Operators.typedefof
Multiple items
val seq : sequence:seq<'T> -> seq<'T>

Full name: Microsoft.FSharp.Core.Operators.seq

--------------------
type seq<'T> = System.Collections.Generic.IEnumerable<'T>

Full name: Microsoft.FSharp.Collections.seq<_>
val t2 : System.Type
namespace System.Collections.Generic
type IEnumerator<'T> =
  member Current : 'T

Full name: System.Collections.Generic.IEnumerator<_>
val enum : value:int32 -> 'U (requires enum)

Full name: Microsoft.FSharp.Core.Operators.enum
System.Collections.IEnumerable.GetEnumerator() : System.Collections.IEnumerator
val failwith : message:string -> 'T

Full name: Microsoft.FSharp.Core.Operators.failwith
Next Version Raw view Test code New version

More information

Link:http://fssnip.net/1J
Posted:13 years ago
Author:Dan Finch
Tags: reflection , generics