Given:
public class MyClass
{
private static readonly Dictionary<string,int> mydict = CreateDictionary();
private static Dictionary<string,int> CreateDictionary() { ... }
}
Is this done synchronously? (ie can two quick instantiations of MyClass
cause CreateDictionary()
to be called twice?
Yes, it's thread safe. Is the C# static constructor thread safe?
Static constructors are guaranteed to be run only once per application domain, before any instances of a class are created or any static members are accessed. http://msdn.microsoft.com/en-us/library/aa645612.aspx
Static field initialization is part of the static constructor. The fact that the field is readonly
doesn't change anything
Some IL code as requested (taken from Try Roslyn http://goo.gl/ayIMG0 )
.method private hidebysig specialname rtspecialname static
void .cctor () cil managed
{
// Method begins at RVA 0x205f
// Code size 11 (0xb)
.maxstack 8
IL_0000: call class [mscorlib]System.Collections.Generic.Dictionary`2<string, int32> MyClass::CreateDictionary()
IL_0005: stsfld class [mscorlib]System.Collections.Generic.Dictionary`2<string, int32> MyClass::mydict
IL_000a: ret
} // end of method MyClass::.cctor
where .cctor
is the special name of the static constructors. The call to CreateDictionary
and the assignment to mydict
are quite evident.
The accepted answer is correct; the initialization will happen either zero or one times but never twice. But I would add a caveat. In your example the CLR and the C# language reserve the right to initialize the field earlier than you might expect. If you write:
public class MyClass
{
private static readonly Dictionary<string,int> mydict = CreateDictionary();
static MyClass() {}
then the CLR and C# guarantee that the field will be initialized when the first static method is called on MyClass
or when the first instance of MyClass
is created. If you omit the static constructor then the CLR and C# are permitted, but not required, to initialize the field at any time prior to those events. In particular, suppose you have a method M
which calls a static method of MyClass
. The CLR might decide to run the static initializer of MyClass.mydict
when M
is jitted , and not when M
actually calls the static method . This can in some rare situations lead to surprising results.
Do a web search on the beforefieldinit
optimization for more details. Jon Skeet has a good article on this.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.