我正在制作一个项目,其中有单独的源文件/模块,这些源文件/模块将功能添加到更高级别文件中包含的单个Dictionary中。但是,我发现这些源文件中没有任何东西可以单独求值,即使是不带参数或代码的函数,甚至都不在函数内部。
因此,没有将任何内容添加到字典中。有没有办法自动强制评估模块中的完整功能调用?我将举一个我想做的事的例子:
Registry.fs:
let private functions = Dictionary<string, MessageHandler>()
let add type handler =
functions.Add(type, handler)
Handler1.fs:
Registry.add "type1" (fun m -> ....
)
Handler2.fs:
Registry.add "type2" (fun m -> ....
)
答案 0 :(得分:3)
我相信您需要查看this relevant topic。当F#代码被编译为IL时,松散的方法调用将作为封装类型/模块的static
构造函数内部的方法调用进行编译。仅看图片,这大致相当于以下C#代码:
static class Handler1 {
static Handler1() {
// this is the static constructor
Registry.add "type1" ....
}
}
在.NET static
中,构造函数未急于初始化 1 。这意味着,如果要使.NET运行时调用Handler1
静态构造函数,则需要访问Handler1
类型的静态成员。
在静态上下文中使用类型的示例是
公开一个易于访问的静态成员/方法:
module Handler1 =
[<Literal>]
let Name = "Handler1"
从您的代码访问该静态成员,例如main方法:
[<EntryPoint>]
let main args =
printf Handler1.Name
上面的行将强制.NET运行时加载Handler1
类型的静态上下文,如果该类型首次被您的代码枚举,则将导致调用静态构造函数。 。如果您的代码从未遇到给定类型的静态上下文(任何静态成员或方法),则它将永远不会初始化-静态构造函数将永远不会被调用。
此行为是.NET框架的设计(与选择的语言(C#,F#,VB等)无关,它们都编译为类似的IL)。关键是不要按从未实际使用过的类型分配不必要的资源。
1 在.NET 4之前,执行代码首次遇到给定类型时,将初始化静态类型上下文,而无论用户代码是与该实例的实例还是静态成员进行交互类型。在.NET 4之后,这一情况稍有变化-仅当用户代码与该类型的静态成员进行交互时,才会初始化静态上下文。