[英]Static constructors in F# - when do they run?
我正在尝试用F#创建单身的各种方法,这样我就能更好地理解细微之处。 我不知道单身模式在F#中是否有用 ,但我想尝试一下。 我对这些单例实例中涉及静态构造函数的一个结果感到惊讶。 首先,我将向您展示我的代码,然后我会详细介绍我的问题。
在一个名为TrySingleton
项目中,我创建了三个模块。 这是Eager.fs
:
module TrySingleton.Eager
type EagerClass() =
do
printfn "Initializing eager class..."
static do
printfn "Static constructor of eager class"
let Instance = EagerClass()
这是Lazy.fs
:
module TrySingleton.Lazy
type LazyClass() =
do
printfn "Initializing lazy class..."
static do
printfn "Static constructor of lazy class"
let Instance = lazy LazyClass()
以下是我在Main.fs
调用它们的Main.fs
:
module TrySingleton.Main
[<EntryPoint>]
let main argv =
printfn "Starting main with args %A" argv
printfn "Accessing eager instance:"
printfn "%A" Eager.Instance
printfn "Accessing lazy instance:"
printfn "%A" Lazy.Instance.Value
printfn "Accessing eager instance again:"
printfn "%A" Eager.Instance
printfn "Accessing lazy instance again:"
printfn "%A" Lazy.Instance.Value
printfn "Success; exiting."
0
我期待Eager
类的静态构造函数在程序启动时立即运行,并且不确定Lazy
类的静态构造函数何时运行。 但是,这是我得到的输出:
Starting main with args [||]
Accessing eager instance:
Static constructor of eager class
Initializing eager class...
TrySingleton.Eager+EagerClass
Accessing lazy instance:
Static constructor of lazy class
Initializing lazy class...
TrySingleton.Lazy+LazyClass
Accessing eager instance again:
TrySingleton.Eager+EagerClass
Accessing lazy instance again:
TrySingleton.Lazy+LazyClass
Success; exiting.
似乎Eager
课程并不像我想象的那样渴望。 它的静态构造函数仅在我第一次尝试访问实例时运行,而我认为静态类构造函数将在程序启动时运行。
我想我没有留下太多问题,除了问:这是否记录在任何地方? 我想念哪些文档会讨论何时运行类的静态构造函数?
我设法在官方F#文档中找到答案,我很少再看,因为http://fsharpforfunandprofit.com是如此优秀的资源。 但是官方F#文档中的Constructors文章说(强调我的):
除了指定用于创建对象的代码之外,还可以在类型首次用于在类型级别执行初始化之前执行的类类型中创建静态
let
和do
绑定。
有后续链接到let
绑定在类和do
绑定在类的文章,其中说(重点煤矿,再次):
静态
let
绑定是类的静态初始化程序的一部分,保证在首次使用类型之前执行。
和
类定义中的
do
绑定在构造对象时执行操作,或者对于静态do
绑定, 在首次使用类型时执行 。
所以看起来我可以回答我自己的问题:答案是我最初的期望是错误的。 静态构造函数不一定会在程序启动时运行,但只有当第一次使用这个类。 这意味着如果你在两个不同的类中使用Singleton模式,其中一个依赖于另一个,它们的构造函数(和静态构造函数)将按给定依赖关系的顺序运行。 (当然,在这种情况下可能有更好,更实用的方法来设计代码;我将其用作说明而不是对该设计的认可。)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.