Create an Action <'T> instance using reflection

How to create an instance Action<'T>using reflection? Here is what I have:

let makeAction (typ:Type) (f:'T -> unit) = 
  let actionType = typedefof<Action<_>>.MakeGenericType(typ)
  let converter = FSharpFunc.ToConverter(f)
  Delegate.CreateDelegate(actionType, converter.Method)

which barfs with:

System.ArgumentException: Binding errors to the target method.
in System.Delegate.CreateDelegate (Type of type, MethodInfo method, Boolean throwOnBindFailure)

'Tis an interface that is implemented typ.

+5
source share
1 answer

I think there are two problems. The first is that you need to call overload CreateDelegate, which takes three arguments. The optional argument indicates the instance on which the method should be called.

, Converter<'T, unit> , Microsoft.FSharp.Core.Unit, , void. , , . , #, void :

open System

type Wrapper<'T>(f:'T -> unit) =
  member x.Invoke(a:'T) = f a

let makeAction (typ:Type) (f:'T -> unit) = 
  let actionType = typedefof<Action<_>>.MakeGenericType(typ)
  let wrapperType = typedefof<Wrapper<_>>.MakeGenericType(typ)
  let wrapped = Wrapper<_>(f)
  Delegate.CreateDelegate(actionType, wrapped, wrapped.GetType().GetMethod("Invoke"))

makeAction (typeof<int>) (printfn "%d")

. ( ).

+3

All Articles