【问题标题】:How to do typeof of a module in a fsx file?如何在 fsx 文件中对模块进行 typeof?
【发布时间】:2011-02-24 08:51:47
【问题描述】:
假设我有一个包含以下代码的 Foo.fsx 脚本:
module Bar =
let foobar = "foo"+"bar"
open Bar
let a = System.Reflection.Assembly.GetExecutingAssembly()
let ty = a.GetType("Foo.Bar") // but it returns null here
我怎样才能做到这一点?谢谢!
【问题讨论】:
标签:
reflection
f#
f#-interactive
【解决方案1】:
这是一个棘手的问题,因为 F# 交互式将所有类型编译为具有一些重命名的类型(并且正在执行的程序集可以包含同一类型的多个版本)。
我设法使用一个简单的技巧来做到这一点 - 您可以向模块添加一个额外的类型 - 然后您可以使用 typeof<..> 获取有关此类型的信息。模块内部的类型被编译为嵌套类型,因此您可以从这个(嵌套)类型中获取代表模块的类型的名称:
module Bar =
let foobar = "foo"+"bar"
type A = A
// Get type of 'Bar.A', the name will be something like "FSI_0001+Bar+A",
// so we remove the "+A" from the name and get "FSI_0001+Bar"
let aty = typeof<Bar.A>
let barName = aty.FullName.Substring(0, aty.FullName.Length - "+A".Length)
let barTy = aty.Assembly.GetType(barName)
// Get value of the 'foobar' property - this works!
barTy.GetProperty("foobar").GetValue(null, [| |])
您可以简单地搜索程序集中的所有类型以查找+Bar。那也行。上述技巧的好处是您获得了对该类型的特定版本的引用(如果您以交互方式多次运行代码,您将获得对与当前Bar.A 类型对应的模块的引用)
作为旁注,有一些关于在 F# 的未来版本中支持 moduleof<Bar>(或类似的东西)的讨论 - 这有点不雅,因为它不是像 typeof 这样的真正函数/值,但是会很有用的!