beforefieldinit
.NET
CIL
initialization
performance

What does beforefieldinit flag do?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

Introduction

beforefieldinit is a CLR type flag that changes when the runtime is allowed to run a type initializer. It matters because static initialization in .NET is not just about assigning field values; it also affects observable program behavior, ordering, and thread safety. The short version is that beforefieldinit gives the runtime more freedom to initialize a type earlier than the exact moment you first touch a static field.

What the Flag Means

When a type is marked beforefieldinit, the CLR may run its type initializer at any time before the first access to a static field of that type. Without that flag, the runtime must trigger initialization at a more precise point before the first use of the type.

This is easiest to understand by comparing two classes.

csharp
1using System;
2
3class LazyEnough
4{
5    public static readonly int Value = Init();
6
7    private static int Init()
8    {
9        Console.WriteLine("LazyEnough initialized");
10        return 42;
11    }
12}
13
14class Precise
15{
16    static Precise()
17    {
18        Console.WriteLine("Precise initialized");
19    }
20
21    public static readonly int Value = 42;
22}

The Precise class has an explicit static constructor, also called a type initializer. That usually prevents the compiler from marking the type beforefieldinit. The LazyEnough class has static field initialization but no explicit static constructor, so the compiler is free to emit beforefieldinit.

Why an Explicit Static Constructor Changes the Semantics

An explicit static constructor tells the runtime that initialization timing is observable and should happen exactly when the specification requires for that kind of type. That makes the initialization point more deterministic from the program's point of view.

In practice, that means developers often add a static constructor when they need strong ordering guarantees.

csharp
1using System;
2
3class Config
4{
5    public static readonly string Mode;
6
7    static Config()
8    {
9        Mode = Environment.GetEnvironmentVariable("APP_MODE") ?? "prod";
10        Console.WriteLine("Config initialized");
11    }
12}

Here the initialization has a visible side effect and depends on runtime state, so precise timing may matter.

beforefieldinit Is About Permission, Not a Promise

A common mistake is to think the flag guarantees "lazy initialization right before first field access." It does not. It grants the CLR permission to initialize the type at any earlier convenient moment, as long as that happens before the first static field read or write.

That means code with side effects in static initialization should not rely on subtle timing if the type can be marked beforefieldinit.

In other words:

  • the runtime may initialize the type later
  • the runtime may initialize the type earlier
  • your code should not depend on the exact instant unless you intentionally force that behavior with a static constructor

Looking at the IL Behavior

You usually do not write the flag directly in C#, but it appears in the generated IL metadata. Tools such as ILDasm or ILSpy show it.

A class without an explicit static constructor may appear like this in IL:

il
1.class private auto ansi beforefieldinit LazyEnough
2       extends [System.Runtime]System.Object
3{
4}

Once you add a static constructor, the beforefieldinit marker typically disappears.

Performance and Correctness

Most of the time, the performance difference is tiny and not worth micro-optimizing. The real reason to care is correctness.

If static initialization only assigns immutable constants or cheap cached values, beforefieldinit is usually fine. If initialization does observable work, touches external state, logs messages, or depends on ordering with other types, you should understand the difference and possibly use an explicit static constructor.

That does not mean "always add a static constructor." It means "do not accidentally depend on timing that the runtime is free to change."

Common Pitfalls

  • Assuming beforefieldinit means strictly lazy initialization at the last possible moment.
  • Writing side-effect-heavy static initialization and depending on exact timing.
  • Adding a static constructor only for style and changing initialization semantics unintentionally.
  • Treating the flag as a major performance knob instead of a correctness detail.
  • Forgetting that the compiler decides whether to emit the flag based on the type definition.

Summary

  • 'beforefieldinit lets the CLR initialize a type at any time before its static fields are first accessed.'
  • Types with an explicit static constructor usually do not get the flag.
  • The flag changes initialization timing semantics more than performance.
  • Do not rely on exact static initialization timing unless you force it intentionally.
  • Use a static constructor when initialization order or side effects must be precise.

Course illustration
Course illustration

All Rights Reserved.