Reflection 如何在fsx文件中对模块进行类型化?
假设我有一个Reflection 如何在fsx文件中对模块进行类型化?,reflection,f#,f#-interactive,Reflection,F#,F# Interactive,假设我有一个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 我怎样才能做到这一点?谢谢 这是一个棘手的问题,因为F#interactive会将所有类型编译成具有一些损坏名称的
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
我怎样才能做到这一点?谢谢 这是一个棘手的问题,因为F#interactive会将所有类型编译成具有一些损坏名称的类型(执行程序集可以包含同一类型的多个版本) 我使用了一个简单的技巧成功地做到了这一点——你可以在模块中添加一个额外的类型——然后你可以使用
typeof
来获取关于这个类型的信息。模块内的类型被编译为嵌套类型,因此您可以从该(嵌套)类型获取表示模块的类型的名称:
模块条=
让foobar=“foo”+“bar”
A型=A型
//获取'Bar.A'类型,名称类似于“FSI_0001+Bar+A”,
//因此,我们从名称中删除“+A”,得到“FSI_0001+Bar”
设aty=typeof
让barName=aty.FullName.Substring(0,aty.FullName.Length-“+A”.Length)
让barTy=aty.Assembly.GetType(barName)
//获取“foobar”属性的值-这很有效!
GetProperty(“foobar”).GetValue(null,[| |]]
您可能只需搜索程序集中的所有类型,查找+Bar
。那也行。上述技巧的好处是,您可以获得对类型特定版本的引用(如果您以交互方式多次运行代码,您将获得对当前条.a
类型对应的模块的引用)
作为旁注,关于在未来版本的F#中支持
moduleof
(或类似的东西)有一些讨论-这有点不雅观,因为它不像typeof
,而是一个真正的函数/值,但它将非常有用 FSI也不能很好地处理名称空间()交叉引用:
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, [| |])