What does beforefieldinit flag do?

.NetCil

.Net Problem Overview


What does beforefieldinit flag do? When I look into the IL of my class I see this flag but I don't know what this flag is actually doing?

.Net Solutions


Solution 1 - .Net

See my article on this very issue.

Basically, beforefieldinit means "the type can be initialized at any point before any static fields are referenced." In theory that means it can be very lazily initialized - if you call a static method which doesn't touch any fields, the JIT doesn't need to initialize the type.

In practice it means that the class is initialized earlier than it would be otherwise - it's okay for it to be initialized at the start of the first method which might use it. Compare this with types which don't have beforefieldinit applied to them, where the type initialization has to occur immediately before the first actual use.

So, suppose we have:

public static void DoSomething(bool which)
{
    if (which)
    {
        FirstType.Foo();
    }
    else
    {
        SecondType.Bar();
    }
}

If both types have beforefieldinit applied to them (which in C# they do by default unless the type has a static constructor) then they'll both be initialized at the start of the DoSomething method (usually - it's not guaranteed). If they don't have beforefieldinit then only one of them will be initialized, based on the flag.

This is why it's common to use a static constructor (even an empty one!) when implementing the singleton pattern.

Solution 2 - .Net

Looks like it is going to change in 4.6

https://github.com/dotnet/coreclr/issues/1193

Solution 3 - .Net

If marked BeforeFieldInit then the type's initializer method is executed at, or sometime before, first access to any static field defined for that type.

If not marked BeforeFieldInit then that type's initializer method is executed at first access to any static or instance field of that type, or first invocation of any static, instance or virtual method of that type.

Solution 4 - .Net

When a type declares an explicit static constructor, the just-in-time (JIT) compiler adds a check to each static method and instance constructor of the type to make sure that the static constructor was previously called. Static initialization is triggered when any static member is accessed or when an instance of the type is created. However, static initialization is not triggered if you declare a variable of the type but do not use it, which can be important if the initialization changes global state.

When all static data is initialized inline and an explicit static constructor is not declared, Microsoft intermediate language (MSIL) compilers add the beforefieldinit flag and an implicit static constructor, which initializes the static data, to the MSIL type definition.

When the JIT compiler encounters the beforefieldinit flag, most of the time the static constructor checks are not added. Static initialization is guaranteed to occur at some time before any static fields are accessed but not before a static method or instance constructor is invoked. Note that static initialization can occur at any time after a variable of the type is declared.

Static constructor checks can decrease performance. Often a static constructor is used only to initialize static fields, in which case you must only make sure that static initialization occurs before the first access of a static field. The beforefieldinit behavior is appropriate for these and most other types. It is only inappropriate when static initialization affects global state and one of the following is true:

The effect on global state is expensive and is not required if the type is not used.

The global state effects can be accessed without accessing any static fields of the type.

For more information https://docs.microsoft.com/en-us/dotnet/fundamentals/code-analysis/quality-rules/ca1810

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEmbedd_0913View Question on Stackoverflow
Solution 1 - .NetJon SkeetView Answer on Stackoverflow
Solution 2 - .NetOmariOView Answer on Stackoverflow
Solution 3 - .NetKetan PandhareView Answer on Stackoverflow
Solution 4 - .NetEldar MahmudovView Answer on Stackoverflow