【问题标题】: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&lt;Bar&gt;(或类似的东西)的讨论 - 这有点不雅,因为它不是像 typeof 这样的真正函数/值,但是会很有用的!

【讨论】:

    猜你喜欢
    • 2017-10-13
    • 1970-01-01
    • 2015-06-17
    • 2020-09-27
    • 2016-04-02
    • 2011-01-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多