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

Reflection 如何获取F中模块的类型#,reflection,f#,Reflection,F#,如何获取模块的“System.Type” 例如,模块: module Foo = let bar = 1 这是行不通的: printfn "%s" typeof<Foo>.Name 如果有一个操作符的模块,那当然很好。。。因为没有,所以最简单的方法可能是使用F#PowerPack中的元数据库: #r "FSharp.PowerPack.Metadata.dll" open Microsoft.FSharp.Metadata // get .NET assembly

如何获取模块的“System.Type”

例如,模块:

module Foo =
     let bar = 1
这是行不通的:

printfn "%s" typeof<Foo>.Name

如果有一个
操作符的
模块,那当然很好。。。因为没有,所以最简单的方法可能是使用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
调用执行类似的操作,但这更取决于您对模块所采用的编译形式的充分理解。

模块名称不是一种类型

列表中的
列表。map
let(a:List)=[1;2;3]
是不同的


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

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

module Foo =  
    type internal Marker = interface end
    let t = typeof<Marker>.DeclaringType
模块Foo=
类型内部标记=接口结束
设t=typeof.DeclaringType
也可以使用。首先,在某处定义此帮助器函数:

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 @>
模块名称=
让rec private moduleType=getModuleType

希望这能有所帮助。

在这里好奇。你为什么要这么做?您知道模块的名称Foo,我认为F#没有能力将模块作为值传递。谢谢。需求很简单,我需要一些自动化。我可以通过反思来做到这一点。PowerPack.Metadata允许迭代模块,但可能有更简单的方法。我也需要为我正在编写的库的强类型API这样做。交叉引用:我关心的是“FSharpType.IsModule(System.Type)”,所以模块是类型,至少在CLR术语中是这样。静态类(Type)的名称编译到的
列表
模块可能是
列表模块
。主要问题是'FSharpAssembly.FromAssembly asm'加载所有类型。同时减少类型安全。@Mike-我不知道你说的“减少类型安全”是什么意思。。。无法将模块用作泛型类型参数,因此必须使用字符串。这是不幸的,但不可避免的。这仍然需要一个电源组来完成,还是5年后有更好的方法呢?虽然我将第二部分修改为:
modulesomename=let rec moduleType=getModuleType
,然后是
SomeName.moduleType应输出类型信息。
module SomeName =
    let rec private moduleType = getModuleType <@ moduleType @>