C# 静态构造函数:特性、执行顺序与实战解析

C# 构造函数执行顺序深度解析:从基类到静态构造函数的5步流程 本文深入解析C#构造函数执行顺序,从基类到静态构造函数的5步流程,帮助开发者掌握对象初始化的底层逻辑。通过典型场景分析,避免初始化陷阱,提升代码健壮性和可维护性。特别关注静态构造函数的特殊行为和继承链中的构造函数调用。 阅读详情

静态构造函数是 C# 中用于初始化类的静态成员的特殊构造函数,它在类的生命周期中扮演着独一无二的角色。本文将从核心特性、执行顺序、代码实战三个维度,全面解析静态构造函数,并补充静态与非静态成员的核心区别,帮助开发者彻底掌握这一关键语法。

一、静态构造函数的核心特点

静态构造函数是专门用于初始化类的静态成员的特殊方法,其核心特性可总结为以下几点:

1.语法限制:

  • 必须以static修饰,且不允许添加任何访问修饰符(public/private等);
  • 只能是无参构造函数,一个类中最多只能有一个静态构造函数;
  • 无法手动调用,由 CLR(公共语言运行时)自动触发执行。

2.执行时机:

静态构造函数会在以下两种场景中首次触发类初始化时执行,且整个程序生命周期内仅执行一次:

  • 创建该类的第一个实例时;
  • 访问该类的任意静态成员(静态变量、静态方法、静态属性)时。

3.核心作用:

用于初始化类的静态成员(如给静态变量赋值、初始化静态资源),而非实例成员。

二、静态构造函数的执行顺序

类的初始化遵循 “先静态、后实例;先基类、后派生类” 的核心规则,完整执行顺序如下:

  1. 派生类的静态变量(初始化);
  2. 派生类的静态构造函数(执行);
  3. 基类的静态变量(初始化);
  4. 基类的静态构造函数(执行);
  5. 基类的实例变量(初始化);
  6. 基类的实例构造函数(执行);
  7. 派生类的实例变量(初始化);
  8. 派生类的实例构造函数(执行)。
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# 中初始化类静态成员的核心工具,其核心特性可概括为 “无参、无访问修饰符、自动执行、仅执行一次”;执行顺序遵循 “先静态后实例、先基类后派生类” 的规则;理解静态与非静态成员的区别,是正确使用静态构造函数的前提。在实际开发中,静态构造函数常用于初始化全局共享的静态资源、配置项等场景,合理使用可提升代码的规范性和可维护性。

从M350 RTK到E-Port:解锁大疆无人机多负载协同与PSDK V3开发新范式 本文深入解析了大疆M350 RTK无人机搭载的E-Port智能接口与全新的PSDK V3开发套件,如何共同实现多负载协同作业的范式转变。E-Port集成了供电与高速数据总线,而PSDK V3通过统一的设备模型与服务机制,大幅降低了第三方负载的开发门槛与集成复杂度,使构建如智能巡检等复杂空中作业系统变得更加高效和标准化。 阅读详情

相关推荐

深度强化学习:Actor-Critic、A2C、A3C

Actor-Critic算法是强化学习中常用的一种方法,policy-based,通过演员和评论员或者是策略网络和价值网络的结合进行学习

weixin_51995147的博客 1427

c#中的静态构造函数

静态构造函数是C#的一个新特性,其实好像很少用到。不过当我们想初始化一些静态变量的时候就需要用到它了。这个构造函数是属于类的,而不是属于哪里实例的,就是说这个构造函数只会被执行一次。也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用。 复制代码 代码如下: class SimpleClass { // Static constructor static Simple

u011555996的博客 1713

安路科技FPSoC开发实战:从芯片特性到边缘计算应用

本文深入解析安路科技FPSoC芯片在边缘计算领域的开发实战,重点介绍SALDRAGON系列芯片的异构计算架构优势,包括RISC-V/ARM处理器与FPGA的协同工作。通过工业控制和智能视觉应用案例,展示硬件加速实现与低功耗设计技巧,帮助开发者高效利用FPSoC进行边缘计算应用开发。

weixin_29248611的博客 375

静态构造函数

一、定义  由名称可知,静态构造函数(也称为类型构造函数)包含“静态”和“构造函数”两个特点。第一个特点决定了它与静态函数类似,只能使用静态成员;第二个特点决定了它与构造函数类似,具有初始化作用,并且没有返回值。  与构造函数(针对实例对象)不同的是,静态构造函数(针对类)只执行一次,并且是在第一个实例对象创建前被调用,所以它可以用于那些只需要执行一次的操作;而且它不允许有public等修饰符,由...

cabicmi的博客 5385

【报错】sqli-labs靶场搭建出现“Unable to connect to the database: security”

搭建sqli-labs靶场时,“Unable to connect to the database: security”报错解决

九芒星的博客 2991

ESP8266红外控制美的空调:从协议解析到Home Assistant集成

红外遥控技术作为一种经典的非接触式控制方式,其原理是通过红外发光二极管发射经过特定频率调制的光信号来传递指令。在物联网和智能家居领域,利用微控制器如ESP8266模拟红外信号,成为将传统家电接入智能生态系统的关键技术。这项技术通过精准解析和生成符合设备厂商私有协议的红外编码,实现了对空调、电视等设备的远程与自动化控制,具有很高的实用价值。本文聚焦于美的空调的红外协议,深入探讨了其脉冲宽度调制(PWM)和全量式编码的特点,并提供了基于ESP8266的完整解决方案,包括硬件连接、库函数API详解以及如何将其无缝

weixin_30718391的博客 400

[详解]C#静态构造函数

对于静态构造函数的详细总结

吴彦祖的博客 1789

matlab锅炉 pid仿真,基于Matlab锅炉仿真.doc

基于Matlab锅炉仿真内蒙古科技大学MATLAB课程设计任务书2012题 目:锅炉汽包水位控制系统学生姓名:林三彪学 号:0967112127专 业:测控技术与仪器班 级:2009-1指导教师:梁 丽摘 要锅炉是化工、炼油、发电、造纸和制糖等工业生产过程中必不可少的重要动力设备。锅炉往往成了不少工厂不可缺少的一部分,因而,对锅炉设备中的自动控制系统进行分析研究是必要的...

weixin_29133981的博客 1096

C#--静态构造函数

静态构造函数是在构造函数方法前面添加了static关键字之后形成的,并且没有修饰符(public,private),没有参数。 静态构造函数的特点: 静态构造函数没有修饰符修饰(public,private),因为静态构造函数不是我们程序员调用的,是由.net 框架在合适的时机调用的。 静态构造函数没有参数,因为框架不可能知道我们需要在函数中添加什么参数,所以规定不能使用参数。 静态构造函...

qq826364410的专栏 1947

手把手教你学Simulink--基础储能管理场景实例:基于Simulink的锂电池健康状态(SOH)在线评估仿真

本文详细介绍了基于Simulink的锂电池健康状态(SOH)在线评估仿真方法。主要内容包括:1)SOH定义与量化指标(容量SOH、内阻SOH及综合SOH);2)基于Thevenin模型参数辨识和递推最小二乘法(RLS)的在线评估原理;3)100次充放电循环的仿真场景设置;4)Simulink建模步骤(主电路搭建、核心模块实现及信号流连接);5)仿真结果分析,显示SOH评估误差<2%,响应时间45秒,满足在线评估需求;6)提出多参数融合评估、深度学习辅助辨识等优化方向。该方法为储能系统寿命管理提供了有效

MHD0815的博客 181

微信小程序转发功能异常报错 由于小程序违规分享功能暂时无法使用的解决办法

小程序右上角转发功能被封,不代表你违规了,而可能是你没认证、没备案!很多功能都是“先合规、后开发”,踩坑就晚了,别像我一样绕了三圈才发现问题。

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 2607

C#的静态构造函数.cctor

静态构造函数操作的是类(而非其实例的)成员。静态构造函数(.cctor)的一些特点:1. 声明和定义形式上,只能有static一个修饰符,不能有任何修饰符和返回值(也不能有void)。2. 不能被显示调用,由CLR调用。3. 最多只能调用一次。4. 静态构造函数中只能调用静态字段和静态属性,方法等,不能操作实例字段,属性,方法等。5. 静态构造函数需要时必须显示定义,只能最多一个。6. ...

babao4028的博客 1024

Archery通过OpenResty代理转发后登录一直提示Forbidden

测试几遍,连账号密码都没用验证,因为不管输什么都是提示Forbidden。找到配置文件settings.py,下面命令可到配置文件路径。回到页面刷新,随便输入个账号密码,验证失败证明请求成功了。查看Preview,提示CSRF验证失败,请求被中断。域名:dba.hkeasyspeed.com。打开开发者工具查看,网络里面可以看到报403。添加一条配置,把你配置域名添加进去。可以看到页面可以正常访问到。进入Archery容器。重启Archery容器。正常输入账号密码,OK。

万物皆可学 3143

关于 静态构造函数

关于C#静态构造函数的几点说明   静态构造函数是C#的一个新特性,其实好像很少用到。不过当我们想初始化一些静态变量的时候就需要用到它了。这个构造函数是属于类的,而不是属于哪里实例的,就是说这个构造函数只会被执行一次。也就是在创建第一个实例或引用任何静态成员之前,由.NET自动调用。    class SimpleClass {     // Static constructor     st...

u014741420的专栏 617

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

浅学C#(12)——实例构造函数、静态构造函数、析构函数

实例构造函数 [构造函数修饰符] 标识符([参数列表] ) [ : base ( [参数列表] ) ] [ : this ( [参数列表] ) ] { 构造函数语句块 } 构造函数修饰符有public、protected、internal、private 构造函数可以重载 :base表示调用直接基类中的实例构造函数 :this调用该类本身所声明的其他构造函数 构造函数语句块既...

衡与墨的博客 1955

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

C# 静态构造函数和静态变量

原文地址:静态构造函数和静态变量 A.X B.Y的那种恶心题目" style="text-decoration:none; color:rgb(65,104,77)">C# 静态构造函数和静态变量 A.X B.Y的那种恶心题目作者:ww9986 先来看一个经典题目: class A     {         public static int X;         static A

lvmengmeng 869

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

C# static的用法详解

目录 一、静态类 1、静态类的主要特性: 2、静态类与私有构造函数区别: 二、静态成员 三、静态方法 四、静态构造函数 五、静态成员的存储 5.1 静态全局变量 定义: 特点: 5.2 静态局部变量 定义: 特点: 5.3 静态数据成员  内存分配: 初始化和定义: 特点: 访问形式: 作用: 5.4 静态成员函数 特点: 作用: 调用形式: 注意: static静态的,不变的,在某个类中只有一个,不会因实例化对象的不同而不同。 static可以修饰...

W_H_M_2018的博客 1万+

c# 静态构造函数与构造函数的调用先后

先上代码: 测试类: /// <summary> /// 构造函数 /// </summary> public RedisHelper() { Console.WriteLine("构造方法"); } s...

aex34027的博客 288

C#静态构造函数及静态变量学习

静态构造函数: (1)用于对静态字段、只读字段等的初始化。               (2)添加static关键字,不能添加访问修饰符,因为静态构造函数都是私有的。         (3)类的静态构造函数在给定应用程序域中至多执行一次:只有创建类的实例或者引用类的任何静态成员才激发静态构造函数 (4)静态构造函数是不可继承的,而且不能被直接调用。             (5)如果类中...

weixin_34130389的博客 151

C#构造函数深度解析:从基础语法到高级应用

本文系统介绍了C#中构造函数的核心概念与应用。主要内容包括:构造函数的定义与特点(与类同名、无返回值、自动调用、可重载);分类与语法(默认构造、参数化构造、重载构造);高级特性(静态构造、私有构造、构造链);继承中的构造调用顺序;以及最佳实践(参数验证、设计原则)。文章通过丰富示例展示了构造函数在领域驱动设计、配置模式等场景的应用,强调了其在确保对象完整性、提高代码可维护性方面的重要作用,并推荐了相关扩展阅读方向。

德仔 5586

C#常用语法之委托、事件、引用、属性访问器、静态构造函数等杂记

1. 委托 (1)C# 中的委托(Delegate)类似于 C 或 C++ 中函数的指针。委托(Delegate) 是存有对某个方法的引用的一种引用类型变量。引用可在运行时被改变。 (2)Delegate的Invoke(委托同步调用)、BeginInvoke(委托异步调用)。BeginInvoke是在主线程之外,另起了一个线程来运行其所需的代码。 (3)BeginInvoke方法触发你的异步方法...

Tepantaryeah的博客 482

C#静态与实例成员初始化顺序详解

在面向对象编程中,成员初始化顺序是影响程序行为的关键因素。静态成员属于类级别,在类型首次被访问时初始化,生命周期持续到应用程序域卸载;实例成员则随对象创建而初始化。理解这两种成员的初始化机制,可以避免常见的NullReferenceException等问题。通过分析C#中的字段、属性、构造函数等核心概念,本文深入探讨了单类及继承体系中的初始化流程,并结合实际案例展示了循环依赖、泛型类等特殊场景的处理方法。掌握这些知识不仅能提升代码质量,还能有效应对技术面试中的相关问题。

weixin_29597551的博客 183

C# 类初始化顺序

类在初始化时的执行顺序,依次如下: 1: 子类静态变量 2: 子类静态构造函数 3: 子类非静态变量 4: 父类静态变量 5: 父类静态构造函数 6: 父类非静态变量 7: 父类构造函数 8: 子类构造函数 对于静态变量与静态构造函数而言, 无论对一个类创建多少个实例,它的静态成员都只有一个副本。 也就是说,静态变量与静态构造函数只初始化一次(在类第一次实例化时) 以下代码: class ...

PinkCoder 1586

C# 类的构造函数 解析

构造函数 构造函数是一种方法,其名称与其类型的名称相同。其方法签名仅包含方法名称和其参数列表;它不包含返回类型。 构造函数的定义规则: (1)C# 语言的构造函数的名称必须与类名相同。(2)构造函数没有返回值。它可以带参数,也可以不带参数。(3)声明类对象时,系统自动调用构造函数。在构造函数中不要做对类的实例进行初始化以外的事情,也不能被显式地调用。(4)构造函数可以重载,从而提供初始化类对象的不同方法;(5)若在声明时未定义构造函数,系统会自动生成默认的构造函数,此时构造函数的函数体为空。(6)静态构..

Unknowncheats的博客 524

C#构造函数详解和析构函数详解

首先来了解下构造函数的定义: C#构造函数是一种特殊的成员函数,它的作用主要用于为对象分配存储空间,对数据成员进行初始化。 接下来看一下他的语法定义形式: |访问修饰符| 标识符 (|参数列表|) |: base(|参数列表|)| |:this(|参数列表|)| { 构造函数语句块; } 解释: 访问修饰符:就是我们大家所熟悉的publ...

dazhen7289的博客 490

C#面试必问:基类子类静态与实例成员初始化顺序全详解

在面向对象编程中,类型初始化与对象初始化是理解继承体系的基石。C# 借助 CLR 在类型首次被使用前触发静态构造函数与静态字段初始化器,而实例成员则通过构造函数链按“基类优先”的次序逐步展开。理解静态成员属于类型、实例成员属于对象这一本质差异,以及 beforefieldinit 等底层优化机制,不仅能准确回答“先静态后实例、先基类后子类”的经典面试题,还能在实际开发中避开因构造函数调用虚方法或静态构造函数相互依赖而引发的诡异 Bug。本文基于完整的代码验证,拆解基类与子类共八步初始化顺序,并梳理面试官最常

weixin_33883104的博客 327
上一篇: C# 委托与事件深度解析:从原理到实战
下一篇: 解析 .NET 核心基石:CTS、CLS 与 CLR 的核心价值与协同作用
bugcome_com
博客等级 码龄3年 32粉丝 131原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

bugcome_com

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值