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")