我有很多模块,在启动程序时应该向某些在更高级别模块中找到的Dictionary添加某些内容。但是,似乎将模块中的表达式和常量编译到Console App时会打包到静态构造函数中,因此,除非明确引用/在程序认为需要它们时,否则不会对它们进行求值。
这里有一些关于初始化模块的问题,人们一致认为不可能强制执行。但是,我还没有看到他们中的任何一个对此进行反思。在C#中,我知道您可以调用类型的静态构造函数,因此我尝试对F#模块进行同样的操作。
我的尝试涉及到向每个模块添加一个自定义属性(MessageHandlerAttribute),该模块包含一个我希望在启动程序时求值的表达式,然后运行以下命令:
let initAllMessageHandlerModules =
Assembly.GetExecutingAssembly().GetTypes()
|> Array.choose (fun typ ->
typ.CustomAttributes
|> Seq.tryFind (fun attr -> attr.AttributeType = typeof<MessageHandlerAttribute>)
|> Option.map (fun _ -> typ))
|> Array.iter
(fun typ -> try typ.TypeInitializer.Invoke(null, null) |> ignore with | ex -> printfn "%A" ex)
但这给了我以下错误: System.NullReferenceException:对象引用未设置为对象的实例。
我还试图与此交换最终的lambda函数:
(fun typ -> try System.Runtime.CompilerServices.RuntimeHelpers.RunClassConstructor(typ.TypeHandle) |> ignore with | ex -> printfn "%A" ex)
但这似乎无济于事。有可能做到这一点吗?