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

Mik*_*liy 20 reflection f#

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

例如模块:

module Foo =
     let bar = 1
Run Code Online (Sandbox Code Playgroud)

这不起作用:

printfn "%s" typeof<Foo>.Name
Run Code Online (Sandbox Code Playgroud)

错误是:

The type 'Foo' is not defined
Run Code Online (Sandbox Code Playgroud)

Phi*_*ord 31

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

module Foo =  
    type internal Marker = interface end
    let t = typeof<Marker>.DeclaringType
Run Code Online (Sandbox Code Playgroud)


kvb*_*kvb 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
Run Code Online (Sandbox Code Playgroud)

不幸的是,这不适用于动态程序集(例如通过F#Interactive生成的程序集).你可以使用vanilla System.Reflection调用做类似的事情,但这更依赖于对模块所采用的编译形式有一个很好的理解.

  • 这仍然需要一个电源组或5年后有更好的方法吗? (4认同)

Nik*_*ird 5

它也可以使用报价来完成.首先,在某处定义这个辅助函数:

open Microsoft.FSharp.Quotations.Patterns

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

然后,您可以定义一个模块并获取其类型:

module SomeName =
    let rec private moduleType = getModuleType <@ moduleType @>
Run Code Online (Sandbox Code Playgroud)

希望这可以帮助.