是否有可能采用FSharp函数并将其转换为动态函数,或者将来会出现这样的FSharp?
let func (a:int) (b:int) : int =
a + b
let dynamicFunc = FSharpFunc.ToDynamicFunc(func)
let argumentList = [1; 2]
let object = dynamicFunc argumentList
let result = object :?> int
看来您目前不得不退回到标准反射(例如:calling a F# function by name),但这种方法似乎非常脆弱。主要是因为它没有真正保证它有效,你必须知道幕后发生了什么。
这样的东西可以用来包装任何函数并动态地做事。
let wrapFun (x:'f) : 'f =
let args = FSharp.Reflection.FSharpType.GetFunctionElements <| x.GetType()
let runner (any:obj list) : obj =
// Do extra things
FSharpFunc.DynamicInvoke x
FSharp.Reflection.FSharpValue.MakeFunction (typeof<'f>, runner) :?> 'f
答案 0 :(得分:0)
F#确实支持动态调用操作符。但你必须实施你的。以下是从http://www.fssnip.net/2U/title/Dynamic-operator-using-Dynamic-Language-Runtime
获取的示例实施// Reference C# implementation of dynamic operations
#r "Microsoft.CSharp.dll"
open System
open System.Runtime.CompilerServices
open Microsoft.CSharp.RuntimeBinder
// Simple implementation of ? operator that works for instance
// method calls that take a single argument and return some result
let (?) (inst:obj) name (arg:'T) : 'R =
// TODO: For efficient implementation, consider caching of call sites
// Create dynamic call site for converting result to type 'R
let convertSite =
CallSite<Func<CallSite, Object, 'R>>.Create
(Binder.Convert(CSharpBinderFlags.None, typeof<'R>, null))
// Create call site for performing call to method with the given
// name and a single parameter of type 'T
let callSite =
CallSite<Func<CallSite, Object, 'T, Object>>.Create
(Binder.InvokeMember
( CSharpBinderFlags.None, name, null, null,
[| CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null);
CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null) |]))
// Run the method call using second call site and then
// convert the result to the specified type using first call site
convertSite.Target.Invoke
(convertSite, callSite.Target.Invoke(callSite, inst, arg))
您可以按照以下方式使用它
// Dynamically invoke 'Next' method of 'Random' type
let o = box (new Random())
let a : int = o?Next(10)
对于params,您必须将它们作为Tuple
传递给
target?method(param1, param2)
这意味着目标方法将其参数作为元组处理,因此,某些模式匹配可能涉及也可能不涉及