使用反射创建 Action<'T> 的实例



如何使用反射创建Action<'T>的实例?我有:

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

系统。ArgumentException:绑定到目标方法错误。
在System.Delegate。CreateDelegate(Type Type, MethodInfo方法,Boolean throwOnBindFailure)

'T是一个接口,由typ实现。

我认为有两个问题。第一个是需要调用CreateDelegate overload,它有三个参数。附加参数指定应在其上调用该方法的实例。

第二个问题是Converter<'T, unit>实际上被编译为返回Microsoft.FSharp.Core.Unit的方法,而不是返回void的方法。我不确定是否有更简单的解决方法,但是您可以定义一个具有方法的包装器。成员被编译成c#的样子,所以在这种情况下单元类型将被编译为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")

EDIT -做了一个小的改变,使它实际工作在您的场景(与接口)

相关内容

  • 没有找到相关文章

最新更新