假设我有一个包含此代码的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
我怎样才能实现这一目标?谢谢!
答案 0 :(得分:4)
这是一个棘手的问题,因为F#interactive将所有类型编译成具有一些受损名称的类型(并且执行程序集可以包含相同类型的多个版本)。
我设法使用一个简单的技巧 - 你可以为模块添加一个额外的类型 - 然后你可以使用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
类型的模块的引用)< / p>
作为旁注,在F#的未来版本中有一些关于支持moduleof<Bar>
(或类似的东西)的讨论 - 这有点不优雅,因为它不是真正的函数/值,如{{1但是它会非常有用!