为何C#两种场景下实例构造函数均先于静态构造函数执行?
Great question! This is all about C#'s static initialization rules—something that trips up a lot of developers at first. Let’s break down exactly what’s happening here.
The Core Rule: Static Field Initializers Run Before Static Constructors
First, let’s recap the official C# language spec for static initialization:
When a class is first accessed (whether creating an instance, accessing a static member, etc.), the CLR triggers static initialization in this fixed order:
- Execute all static field initializers (the code that assigns values to static fields)
- Run the static constructor (the
static ClassName()method)
This order is non-negotiable—static constructors always wait until all static fields have been initialized before they run.
What’s Happening in Your Code?
Look at your Singleton class:
class Singleton { static readonly Singleton _instance = new Singleton(); public static Singleton Instance { get { return _instance; } } private Singleton() { Console.WriteLine("Instance Constructor"); } static Singleton() { Console.WriteLine("Static Constructor"); } }
When your code first touches the Singleton class (either via new Singleton() in scenario 1, or Singleton.Instance in scenario 2), here’s the step-by-step flow:
- The CLR starts static initialization for
Singleton - First, it initializes the static field
_instanceby runningnew Singleton()—this calls the instance constructor, so you see "Instance Constructor" printed first - Once all static fields are initialized, the CLR runs the static constructor, printing "Static Constructor"
Quick Note on Scenario 1
Side note: Your Singleton has a private constructor, so scenario 1’s Singleton s = new Singleton(); won’t actually compile in Program.Main (private constructors can only be called from inside the class itself). But if you made the constructor public, the initialization flow would still be identical to scenario 2—first static field initialization, then static constructor.
How to Reverse the Order (If You Wanted To)
If you wanted the static constructor to run before the instance constructor, you’d move the static field initialization inside the static constructor itself:
class Singleton { static readonly Singleton _instance; public static Singleton Instance { get { return _instance; } } private Singleton() { Console.WriteLine("Instance Constructor"); } static Singleton() { Console.WriteLine("Static Constructor"); _instance = new Singleton(); // Initialize field inside static constructor } }
Now when you run this, "Static Constructor" prints first, followed by "Instance Constructor"—because the instance constructor is called directly from the static constructor, which runs after static field declarations but before any external usage.
Wrap-Up
Your original behavior isn’t a bug or quirk—it’s exactly how C# is designed to work. The key takeaway is that static field initializers always execute before the static constructor, and if those initializers trigger instance creation, the instance constructor will run before the static one.
内容的提问来源于stack exchange,提问作者Arman Sahakyan

