I am experimenting with various ways of creating singletons in F#, so that I understand the subtleties better. I don't know if the singleton pattern is ever useful in F#, but I wanted to experiment. And I was surprised by one result involving static constructors on those singleton instances. First I'll show you my code, and then I'll go into more details about my question.
In one project called TrySingleton
, I created three modules. Here's Eager.fs
:
module TrySingleton.Eager
type EagerClass() =
do
printfn "Initializing eager class..."
static do
printfn "Static constructor of eager class"
let Instance = EagerClass()
Here's Lazy.fs
:
module TrySingleton.Lazy
type LazyClass() =
do
printfn "Initializing lazy class..."
static do
printfn "Static constructor of lazy class"
let Instance = lazy LazyClass()
And here's how I call them, in 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
I was expecting the static constructor of the Eager
class to run immediately on program startup, and wasn't sure when the Lazy
class's static constructor would run. However, here's the output I got:
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.
It seems that the Eager
class is not as eager as I thought it would be. Its static constructor was only run the first time I tried to access the instance, whereas I thought that the static class constructors would run at program startup time.
I guess I don't have much of a question left, except to ask: is this documented anywhere? What documentation did I miss that talks about when static constructors of a class will be run?