Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

If a static readonly member calls a static method to get a value, is it done synchronously?

Given:

public class MyClass
{
    private static readonly Dictionary<string,int> mydict = CreateDictionary();

    private static Dictionary<string,int> CreateDictionary() { ... }
}

Is this done synchronously? (i.e. can two quick instantiations of MyClass cause CreateDictionary() to be called twice?

like image 461
neverendingqs Avatar asked Mar 11 '15 18:03

neverendingqs


People also ask

Are readonly variables static?

A Static Readonly type variable's value can be assigned at runtime or assigned at compile time and changed at runtime. But this variable's value can only be changed in the static constructor. And cannot be changed further. It can change only once at runtime.

What is the difference between the static const and readonly keywords when applied to a type member?

The first, const, is initialized during compile-time and the latter, readonly, initialized is by the latest run-time. The second difference is that readonly can only be initialized at the class-level. Another important difference is that const variables can be referenced through "ClassName.

What is static readonly in C#?

Constant and ReadOnly keyword is used to make a field constant which value cannot be modified. The static keyword is used to make members static that can be shared by all the class objects.

Can a non-static class have static methods C#?

A non-static class can contain static methods, fields, properties, or events. The static member is callable on a class even when no instance of the class has been created. The static member is always accessed by the class name, not the instance name.


2 Answers

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.

like image 66
xanatos Avatar answered Sep 28 '22 06:09

xanatos


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.

like image 32
Eric Lippert Avatar answered Sep 28 '22 08:09

Eric Lippert