Reflection 创建操作实例<';T>;使用反射

Reflection 创建操作实例<';T>;使用反射,reflection,f#,delegates,Reflection,F#,Delegates,如何创建Action的实例我认为有两个问题。第一个是需要调用带有三个参数的CreateDelegate重载。附加参数指定应在其上调用方法的实例 第二个问题是转换器单元)= 成员x.Invoke(a:'T)=fa let makeAction(类型)(f:'T->unit)= 让actionType=typedefof.MakeGenericType(典型) 让wrapperType=typedefof.MakeGenericType(典型) 让包装=包装(f) CreateDelegate(ac

如何创建
Action的实例我认为有两个问题。第一个是需要调用带有三个参数的
CreateDelegate
重载。附加参数指定应在其上调用方法的实例

第二个问题是
转换器单元)=
成员x.Invoke(a:'T)=fa
let makeAction(类型)(f:'T->unit)=
让actionType=typedefof.MakeGenericType(典型)
让wrapperType=typedefof.MakeGenericType(典型)
让包装=包装(f)
CreateDelegate(actionType、wrapped、wrapped.GetType().GetMethod(“调用”))
makeAction(typeof)(printfn“%d”)

编辑-做了一个小改动,使其在您的场景中实际工作(使用界面)

太棒了。谢谢我只是创建了
转换器
来获取
MethodInfo
。我不知道如何从F#函数中获取它。@Daniel-如果你有一个函数
F
,你也可以使用
F.GetType().GetMethod(“Invoke”)
,但这会给你一个返回
单位的方法,所以在这种情况下它不起作用。是的,我第一次尝试了,也有同样的发现。你有什么特别的理由想用反射来做这件事吗?因为这可以简单地做到:
让makeAction(f:'a->unit)=newAction@Ankur:是的,因为我在编译时不知道
'a
(在您的示例中)。不确定我是否正确地理解了您,但此处的
'a
与代码中的
'T
相同,即根据传递的
f
值解析的泛型类型。您需要一个动作类型来包装传递的
f
函数,对吗?@Ankur:无论名称如何,它都是一个类型参数,必须在编译时解析。
let makeAction (typ:Type) (f:'T -> unit) = 
  let actionType = typedefof<Action<_>>.MakeGenericType(typ)
  let converter = FSharpFunc.ToConverter(f)
  Delegate.CreateDelegate(actionType, converter.Method)
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")