Reflection F#动态评估、反射、IL

Reflection F#动态评估、反射、IL,reflection,f#,cil,Reflection,F#,Cil,因为我似乎把95%的编码时间都花在了F#的FSI上,所以我绕道(见:心烦意乱),想写一些实用函数 我感兴趣的特别实用程序是“反汇编”(http://www.cons.org/cmucl/doc/reading-disassembly.html)可以为给定函数转储IL的函数,稍后可能会计算指令、基本静态分析等,通常这只是分散注意力。我已经编写了将byteArrayIL映射到MSIL名称的代码(几乎) 以下是用于从当前模块获取函数名的代码段: let dec_c = MethodBase.GetCu

因为我似乎把95%的编码时间都花在了F#的FSI上,所以我绕道(见:心烦意乱),想写一些实用函数

我感兴趣的特别实用程序是“反汇编”(http://www.cons.org/cmucl/doc/reading-disassembly.html)可以为给定函数转储IL的函数,稍后可能会计算指令、基本静态分析等,通常这只是分散注意力。我已经编写了将byteArrayIL映射到MSIL名称的代码(几乎)

以下是用于从当前模块获取函数名的代码段:

let dec_c = MethodBase.GetCurrentMethod().DeclaringType

System.Reflection.Assembly.GetAssembly(dec_c).GetTypes() 
|> Seq.map (fun x -> x.FullName) //, get_function_instructions x)
这基本正常,因为x.FullName反映了实际的函数名:

FSI_0001
<StartupCode$FSI_0001>.$FSI_0001
FSI_0002
FSI_0002+instructions_of_bytes@24
FSI_0002+remove_null_function_body_bytes@32
FSI_0002+remove_null_function_body_bytes@31-1
FSI_0002+resolve_IL_from_bytes@38
FSI_0002+resolve_IL_from_bytes@36-1
FSI_0002+it@49
FSI_0002+it@50-1
<StartupCode$FSI_0002>.$FSI_0002
FSI_0003
FSI_0003+it@49-2
FSI_0003+it@50-3
<StartupCode$FSI_0003>.$FSI_0003
FSI_0001
.$FSI_0001
FSI_0002
FSI_0002+的说明_bytes@24
FSI_0002+删除功能体_bytes@32
FSI_0002+删除功能体_bytes@31-1
FSI_0002+解决来自_bytes@38
FSI_0002+解决来自_bytes@36-1
FSI_0002+it@49
FSI_0002+it@50-1
.$FSI_0002
FSI_0003
FSI_0003+it@49-2
FSI_0003+it@50-3
.$FSI_0003
因此,我们可以根据函数名轻松编写一个要过滤的函数

不幸的是(可能是由于我的误解),似乎并非所有函数都以这种方式可用,例如,如果我们定义以下简单函数,然后重新运行转储:

(* reload FSI *)
let simple_add x = x + 1
(* rerun the function name dumping *)

FSI_0001
<StartupCode$FSI_0001>.$FSI_0001
FSI_0002
FSI_0002+instructions_of_bytes@24
FSI_0002+remove_null_function_body_bytes@32
FSI_0002+remove_null_function_body_bytes@31-1
FSI_0002+resolve_IL_from_bytes@38
FSI_0002+resolve_IL_from_bytes@36-1
FSI_0002+it@50
FSI_0002+it@51-1
<StartupCode$FSI_0002>.$FSI_0002
(*重新加载FSI*)
让简单的_加上x=x+1
(*重新运行函数名转储*)
FSI_0001
.$FSI_0001
FSI_0002
FSI_0002+的说明_bytes@24
FSI_0002+删除功能体_bytes@32
FSI_0002+删除功能体_bytes@31-1
FSI_0002+解决来自_bytes@38
FSI_0002+解决来自_bytes@36-1
FSI_0002+it@50
FSI_0002+it@51-1
.$FSI_0002
奇怪的是,结果文本中没有“simple_add”函数

想法: 1.也许simple_add函数在被使用之前不会通过反射实现?听起来很奇怪。 2.这可能是其中一个“FSI_0002+It”字符串实际上是我们的函数

问题: 1.为什么输出不反映所有函数名? 2.有更好的方法吗?

我想我在答案上睡了(半睡了),我错了,没有必要列出每个函数的字符串名称

let get_function_instructions (mb : System.Type) = 
  mb.GetMethods() 
  |> Seq.map ...

let find_func_print_instructions f =
  f.GetType()
  |> get_function_instructions 
  |> print_instruction_text

$FSI_0001
似乎是
简单的添加
。我猜这可能是因为您可以定义两次值,所以使用基于模拟行的名称而不是实名,并且FSI有一个从标签到最新模拟名的表。啊。。这是有道理的,但是如果你有两个要检查的函数,或者15,100000,等等,很难猜测它可能是哪个函数,我不认为FSI是为调试和动态操作而设计的:)我知道FSC生成合理的名称(甚至lambda都有它们的父函数名,除了它们的行号和唯一标识符之外)。你可能是对的,但这将是一个很酷的特性!