如何使用反射创建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)
哪个barf:
System.ArgumentException:绑定到目标方法时出错 在System.Delegate.CreateDelegate(Type type,MethodInfo方法,Boolean throwOnBindFailure)
'T
是一个typ
实现的接口。
答案 0 :(得分:4)
我认为有两个问题。第一个是你需要调用带有三个参数的CreateDelegate
重载。附加参数指定应在其上调用方法的实例。
第二个问题是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")
编辑 - 做了一些小改动,让它在你的场景中实际运行(带界面)