静态构造函数是 C# 中用于初始化类的静态成员的特殊构造函数,它在类的生命周期中扮演着独一无二的角色。本文将从核心特性、执行顺序、代码实战三个维度,全面解析静态构造函数,并补充静态与非静态成员的核心区别,帮助开发者彻底掌握这一关键语法。
一、静态构造函数的核心特点
静态构造函数是专门用于初始化类的静态成员的特殊方法,其核心特性可总结为以下几点:
1.语法限制:
- 必须以static修饰,且不允许添加任何访问修饰符(public/private等);
- 只能是无参构造函数,一个类中最多只能有一个静态构造函数;
- 无法手动调用,由 CLR(公共语言运行时)自动触发执行。
2.执行时机:
静态构造函数会在以下两种场景中首次触发类初始化时执行,且整个程序生命周期内仅执行一次:
- 创建该类的第一个实例时;
- 访问该类的任意静态成员(静态变量、静态方法、静态属性)时。
3.核心作用:
用于初始化类的静态成员(如给静态变量赋值、初始化静态资源),而非实例成员。
二、静态构造函数的执行顺序
类的初始化遵循 “先静态、后实例;先基类、后派生类” 的核心规则,完整执行顺序如下:
- 派生类的静态变量(初始化);
- 派生类的静态构造函数(执行);
- 基类的静态变量(初始化);
- 基类的静态构造函数(执行);
- 基类的实例变量(初始化);
- 基类的实例构造函数(执行);
- 派生类的实例变量(初始化);
- 派生类的实例构造函数(执行)。
using System;
// 基类
class BaseClass
{
// 基类静态变量(步骤3)
public static int BaseStaticVar = InitBaseStaticVar();
// 基类实例变量(仅声明,初始化移至构造函数)
public int BaseInstanceVar;
// 基类静态构造函数(步骤4)
static BaseClass()
{
Console.WriteLine("✅ 基类静态构造函数执行");
}
// 基类实例构造函数(步骤6)
public BaseClass()
{
// 初始化基类实例变量(步骤5)
BaseInstanceVar = InitBaseInstanceVar();
Console.WriteLine("✅ 基类实例构造函数执行");
}
// 辅助方法:初始化基类静态变量
private static int InitBaseStaticVar()
{
Console.WriteLine("✅ 基类静态变量初始化");
return 10;
}
// 辅助方法:初始化基类实例变量
private int InitBaseInstanceVar()
{
Console.WriteLine("✅ 基类实例变量初始化");
return 20;
}
}
// 派生类
class DerivedClass : BaseClass
{
// 派生类静态变量(步骤1)
public static int DerivedStaticVar = InitDerivedStaticVar();
// 派生类实例变量(仅声明,初始化移至构造函数)
public int DerivedInstanceVar;
// 派生类静态构造函数(步骤2)
static DerivedClass()
{
Console.WriteLine("✅ 派生类静态构造函数执行");
}
// 派生类实例构造函数(步骤8)
public DerivedClass()
{
// 初始化派生类实例变量(步骤7)
DerivedInstanceVar = InitDerivedInstanceVar();
Console.WriteLine("✅ 派生类实例构造函数执行");
}
// 辅助方法:初始化派生类静态变量
private static int InitDerivedStaticVar()
{
Console.WriteLine("✅ 派生类静态变量初始化");
return 30;
}
// 辅助方法:初始化派生类实例变量
private int InitDerivedInstanceVar()
{
Console.WriteLine("✅ 派生类实例变量初始化");
return 40;
}
}
class Program
{
static void Main()
{
Console.WriteLine("===== 开始创建派生类实例 =====");
DerivedClass derived = new DerivedClass();
// 输出变量值,验证初始化结果
Console.WriteLine("\n===== 变量初始化结果 =====");
Console.WriteLine($"基类静态变量:{BaseClass.BaseStaticVar}");
Console.WriteLine($"派生类静态变量:{DerivedClass.DerivedStaticVar}");
Console.WriteLine($"基类实例变量:{derived.BaseInstanceVar}");
Console.WriteLine($"派生类实例变量:{derived.DerivedInstanceVar}");
}
}
运行结果(关键:符合 C# 初始化顺序)
===== 开始创建派生类实例 =====
✅ 派生类静态变量初始化
✅ 派生类静态构造函数执行
✅ 基类静态变量初始化
✅ 基类静态构造函数执行
✅ 基类实例变量初始化
✅ 基类实例构造函数执行
✅ 派生类实例变量初始化
✅ 派生类实例构造函数执行
===== 变量初始化结果 =====
基类静态变量:10
派生类静态变量:30
基类实例变量:20
派生类实例变量:40
三、静态与非静态成员的核心区别
理解静态构造函数,需先明确静态成员与非静态成员的本质差异:
| 特性 | 静态成员(static 修饰) | 非静态成员(无 static 修饰) |
|---|---|---|
| 归属 | 属于 “类本身”,所有实例共享 | 属于 “类的实例”,每个实例独立拥有 |
| 访问方式 | 类名。静态成员(如Cat.Name) | 实例名。非静态成员(如cat.Name) |
| 初始化时机 | 类加载时(静态构造函数执行前) | 实例创建时(实例构造函数执行前) |
| 生命周期 | 程序启动至结束 | 实例创建至被 GC 回收 |
扩展示例:静态变量的简单应用
以Cat类为例,展示静态变量的声明与使用:
using System;
class Cat
{
// 静态变量:所有猫共享的“品种”
public static string Species = "哺乳纲猫科";
// 非静态变量:每个猫的独立“名字”
public string Name;
// 静态构造函数:初始化静态变量
static Cat()
{
Console.WriteLine($"✅ 静态构造函数初始化:所有猫的品种为「{Species}」");
}
// 实例构造函数:初始化实例变量
public Cat(string name)
{
Name = name;
Console.WriteLine($"✅ 实例构造函数:猫的名字是「{Name}」");
}
}
class Test
{
static void Main()
{
// 访问静态变量(触发静态构造函数执行)
Console.WriteLine($"猫的品种:{Cat.Species}");
// 创建第一个实例
Cat cat1 = new Cat("小白");
// 创建第二个实例
Cat cat2 = new Cat("小黑");
// 验证静态变量共享性
Cat.Species = "家养宠物猫";
Console.WriteLine($"修改后品种:{Cat.Species}");
// 修正:用类名访问静态成员,而非实例
Console.WriteLine($"cat1的品种:{Cat.Species}");
}
}
✅ 静态构造函数初始化:所有猫的品种为「哺乳纲猫科」
猫的品种:哺乳纲猫科
✅ 实例构造函数:猫的名字是「小白」
✅ 实例构造函数:猫的名字是「小黑」
修改后品种:家养宠物猫
cat1的品种:家养宠物猫
四、静态构造函数的常见注意事项
异常处理: 若静态构造函数抛出未处理的异常,该类将永久无法初始化,后续尝试创建实例或访问静态成员时会抛出TypeInitializationException;
执行顺序不可控: CLR 仅保证 “首次使用前执行”,但无法精确控制执行时机(如程序启动时、实例创建时);
与私有构造函数的区别: 私有构造函数用于阻止类被实例化,而静态构造函数用于初始化静态成员,二者可共存;
静态只读变量: 静态构造函数是初始化 “静态只读变量” 的常用方式(尤其是需要复杂逻辑赋值时),如:
public static readonly string ConfigPath;
static ConfigClass()
{
// 从配置文件读取路径(复杂逻辑)
ConfigPath = ReadConfigPath();
}
总结
静态构造函数是 C# 中初始化类静态成员的核心工具,其核心特性可概括为 “无参、无访问修饰符、自动执行、仅执行一次”;执行顺序遵循 “先静态后实例、先基类后派生类” 的规则;理解静态与非静态成员的区别,是正确使用静态构造函数的前提。在实际开发中,静态构造函数常用于初始化全局共享的静态资源、配置项等场景,合理使用可提升代码的规范性和可维护性。
274

被折叠的 条评论
为什么被折叠?



