如何在F#中获取模块的类型

时间:2010-02-19 15:03:19

标签: reflection f#

如何获取模块的'System.Type'?

例如模块:

module Foo =
     let bar = 1

这不起作用:

printfn "%s" typeof<Foo>.Name

错误是:

The type 'Foo' is not defined

4 个答案:

答案 0 :(得分:30)

您可以向模块添加标记类型,然后从中发现模块的类型:

module Foo =  
    type internal Marker = interface end
    let t = typeof<Marker>.DeclaringType

答案 1 :(得分:8)

拥有一个moduleof运算符肯定会很好......因为没有一个,所以最简单的方法就是使用F#PowerPack中的元数据库:

#r "FSharp.PowerPack.Metadata.dll" 
open Microsoft.FSharp.Metadata

// get .NET assembly by filename or other means
let asm = ...

let fasm = FSharpAssembly.FromAssembly asm
let t = fasm.GetEntity("Foo").ReflectionType

不幸的是,这不适用于动态程序集(例如通过F#Interactive生成的程序集)。您可以使用vanilla System.Reflection调用执行类似的操作,但这更依赖于对模块所采用的编译表单的理解。

答案 2 :(得分:5)

也可以使用Quotations完成。首先,在某处定义这个辅助函数:

open Microsoft.FSharp.Quotations.Patterns

let getModuleType = function
| PropertyGet (_, propertyInfo, _) -> propertyInfo.DeclaringType
| _ -> failwith "Expression is no property."

然后,您可以定义一个模块并获得如下类型:

module SomeName =
    let rec private moduleType = getModuleType <@ moduleType @>

希望这有帮助。

答案 3 :(得分:-1)

模块名称不是类型。

ListList.map中的

let (a:List<int>) = [1;2;3]不同。

第一个List是模块名称,第二个是类型。