在 F# 中的编译时获取模块的类型

Get type of a module at compile time in F#

我们知道在 C# 中,我们可以在编译时使用 typeof(OutType) 获取类型的类型,这让我们可以稍后将其传递给属性,因为它是常量表达式。

我看到了 this 问题,但它并没有真正解决编译时的使用问题。

所以我的问题是:有没有办法在 F# 标准库中以编译类型获取给定模块的 System.Type

如果您可以在该模块中引用一个类型(或者如果没有类型则创建一个虚拟类型),您可以这样做:

module MyModule =
    type Dummy = Dummy

let myModule = typeof<MyModule.Dummy>.DeclaringType

F# 在设计上不允许使用其 typeof 运算符获取模块的类型,因为它们不是语言中的第一个 class 概念。

来自 spec,第 13.2 节:

F# modules are compiled to provide a corresponding compiled CLI type declaration and System.Type object, although the System.Type object is not accessible by using the typeof operator.

模块编译为静态 classes 但是,因此可以在运行时使用反射获取类型(这就是 typeof<MyModule.Dummy>.DeclaringType 示例中发生的情况),并且可以获取类型在引用的 F# 程序集中使用 C# 中的 typeof 运算符定义的模块。

对于你想要做的事情,你最好使用 class 而不是模块,因为这样你就可以毫不费力地掌握类型:

type MyFactoryClass = 
    static member TestCases = [ 1; 2; 3 ]

...

[<Test; TestCaseSource(typeof<MyFactoryClass>, "TestCases">] 
let test (arg: int) = ...