如何创建一个名为getFuncName的函数,它接受类型函数(unit - >'a)并返回其名称。
我正在与其中一个C#开发人员交谈,他们说你可以在Func类型上使用.Method属性,如示例 here所示。
我尝试将其转换为F#:
例如将(单位 - >'a)转换为类型Func< _>然后在它上面调用属性,但它总是返回字符串“Invoke”。
let getFuncName f =
let fFunc = System.Func<_>(fun _ -> f())
fFunc.Method.Name
let customFunc() = 1.0
// Returns "Invoke" but I want it to return "customFunc"
getFuncName customFunc
这个问题的一些背景是:
我创建了一个类型为(unit - &gt; Deedle.Frame)的函数数组。我现在想循环调用它们的那些函数并将它们保存到csv,其中csv名称与函数同名。一些假设代码如下:
let generators : (unit -> Frame<int, string>) array = ...
generators
|> Array.iter (fun generator -> generator().SaveCsv(sprintf "%s\%s.csv" __SOURCE_DIRECTORY__ (getFuncName generator)))
这用于脚本意义而不是应用程序代码。
答案 0 :(得分:1)
不确定您是如何搜索信息的,但是对搜索引擎的第一个查询给了我这样的回复:
let getFuncName f =
let type' = f.GetType()
let method' = type'.GetMethods() |> Array.find (fun m -> m.Name="Invoke")
let il = method'.GetMethodBody().GetILAsByteArray()
let methodCodes = [byte OpCodes.Call.Value;byte OpCodes.Callvirt.Value]
let position = il |> Array.findIndex(fun x -> methodCodes |> List.exists ((=)x))
let metadataToken = BitConverter.ToInt32(il, position+1)
let actualMethod = type'.Module.ResolveMethod metadataToken
actualMethod.Name
不幸的是,这段代码仅在F#编译器没有将函数体内联到调用方法时才有效。
取自here
虽然可能有更简单的方法。