C# 从函数中提取函数名

C# 从函数中提取函数名,c#,reflection,f#,C#,Reflection,F#,如何创建一个名为getFuncName的函数,该函数接受类型为(unit->'a)的函数并返回其名称 我正在和一个C#dev交谈,他们说可以对Func类型使用.Method属性,如示例所示 我试着把它转换成F#: 例如,convert(unit->'a)为Func类型,然后调用该类型的属性,但它始终返回字符串“Invoke” 让getFuncName f= 设fFunc=System.Func(fun uz->f()) fFunc.Method.Name 设customFunc()=1.0 //

如何创建一个名为getFuncName的函数,该函数接受类型为(unit->'a)的函数并返回其名称

我正在和一个C#dev交谈,他们说可以对Func类型使用.Method属性,如示例所示

我试着把它转换成F#:

例如,convert(unit->'a)为Func类型,然后调用该类型的属性,但它始终返回字符串“Invoke”

让getFuncName f=
设fFunc=System.Func(fun uz->f())
fFunc.Method.Name
设customFunc()=1.0
//返回“Invoke”,但我希望它返回“customFunc”
getFuncName自定义函数
这个问题的一点背景是:

我创建了一个类型为(unit->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)))
let生成器:(单元->帧)数组=。。。
发电机
|>Array.iter(有趣的生成器->生成器().SaveCsv(sprintf“%s\%s.csv”\uuuu源目录\uuuuuuu(getFuncName生成器)))

这是在脚本意义上使用的,而不是作为应用程序代码使用。

不确定您是如何搜索信息的,但搜索引擎的第一次查询给了我以下响应:

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#编译器没有将函数体内联到调用方法中时,此代码才起作用

取自


虽然可能有一种更简单的方法。

AFAIK你不会很容易得到这个,但也许有一天我们会得到;)奇怪的是,这很容易在C中实现,但在F中却无法实现。如果这是一个XY问题,你想在这里做什么?在所有情况下,F并不是更好的语言为什么没有元组数组,每个都有一个函数及其名称?是的,这是有效的,但请注意代码段下的注释,其中提到在函数内联的地方它不起作用
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