静态构造函数到底执行了多少次?

本文探讨了C#中静态构造函数的执行情况。静态构造函数只在第一次调用时执行一次,后续调用不会再次执行。在并发环境下,静态构造函数的执行也是线程安全的,确保在程序域级别上只会初始化一次,这使得它适用于实现单例模式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我们知道对于class和struct都可以定义构造函数,而构造函数又有实例构造函数和静态构造函数。实例构造函数在每次实例化时,都会执行一次。那静态构造函数是否如此呢?我们先来看一段代码:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConstructorTest
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(CData.Num);///A
            Console.WriteLine(CData.Num);///B           
            Console.ReadLine();
        }
    }

    public class CData
    {
        public static int Num = 0;
        static CData()
        {
            Num++;
        }
    }
}
我们猜测一下执行的结果:

A行输出的是1.这个比较容易想到,因为Num初始为0,在构造函数中执行了Num++,所以结果为1.

那B行输出的呢?会不会又执行了一次Num++,导致输出结果为2?我们来看输出的结果,见下图

<think>好的,我现在需要回答用户关于C#静态构造函数的用法和特性的问题。首先,我应该回顾一下用户提供的引用内容,确保信息的准确性。 用户引用了五个来源,其中提到了静态构造函数的基础概念、与实例构造函数的区别、使用场景(如单例模式)、特性(如无修饰符、无参数、只能执行一次)等。我需要将这些信息整合成一个结构清晰的回答。 首先,我需要明确静态构造函数的定义和基本规则。根据引用[1]和[4],静态构造函数必须与类同名,使用static关键字,不能有访问修饰符或参数,且只能有一个。这些是基本规则,需要首先列出。 接下来是执行时机。引用[4]提到静态构造函数在类首次实例化或静态成员被访问执行,且仅执行一次。需要强调这一点,因为它影响使用场景。 然后是使用场景。用户提供的引用[3]提到了单例模式,引用[5]可能涉及静态成员的初始化。需要将这些场景具体说明,比如初始化静态资源、配置加载等。 还需要比较静态构造函数和实例构造函数的区别,引用[2]和[4]都有相关内容。比如,实例构造函数在每次实例化时调用,而静态构造函数只调用一次,且无访问修饰符。 另外,注意事项也很重要。比如静态构造函数中不能实例化实例变量,只能初始化静态成员,避免耗时操作,以及自动生成的情况(引用[4])。 最后,生成相关问题,确保问题覆盖用户可能感兴趣的其他方面,比如与实例构造函数的对比、单例模式应用、执行时机等。 需要确保回答符合用户的要求:使用中文,数学公式正确,引用标识自然添加,结构清晰。同时检查是否有遗漏的重要特性或规则,比如框架自动生成静态构造函数的情况,或者线程安全方面的优势(如引用[3]中的单例模式)。 总结步骤: 1. 定义和基本规则 2. 执行时机和特性 3. 典型使用场景 4. 与实例构造函数的对比 5. 注意事项 6. 相关问题生成 需要确保各部分信息准确,引用正确,并且语言通俗易懂。同时,避免使用Markdown格式,但按照用户的要求,在回答中使用引用标识。例如,在提到执行时机时引用[4],单例模式时引用[3],静态成员初始化引用[5]等。</think>### C# 静态构造函数的使用场景与规则 #### 一、基本定义与规则 静态构造函数是类初始化静态成员的专用方法,需遵守以下规则: 1. **命名与修饰**:必须与类同名,使用 `static` 关键字,且**不能有访问修饰符**(如 `public`/`private`)[^1][^4]。 2. **参数限制**:**不能包含参数**,因为其调用由.NET框架控制。 3. **唯一性**:每个类最多**一个静态构造函数**,且可与无参实例构造函数共存。 4. **调用权**:由.NET框架在特定时机自动调用,程序员无法直接调用。 #### 二、执行时机与特性 - **触发条件**:当类**首次被实例化**或**静态成员被访问**时执行。 - **执行次数**:整个应用程序生命周期内**仅执行一次**。 - **初始化顺序**:若类包含静态字段且未显式赋值,静态构造函数会先于实例构造函数执行,完成静态成员的初始化。 #### 三、典型使用场景 1. **初始化静态资源** 例如加载配置文件、数据库连接池预建等: ```csharp public class ConfigLoader { public static string ConnectionString; static ConfigLoader() { ConnectionString = File.ReadAllText("config.json"); // 初始化静态字段 } } ``` 2. **实现线程安全的单例模式** 利用静态构造函数**自动执行且线程安全**的特性[^3]: ```csharp public class Singleton { public static readonly Singleton Instance; static Singleton() { Instance = new Singleton(); // 由框架保证线程安全 } private Singleton() { } } ``` 3. **静态成员的复杂初始化** 当静态字段需要非默认值或依赖外部条件时: ```csharp public class MathConstants { public static readonly double Tolerance; static MathConstants() { Tolerance = CalculateOptimalTolerance(); // 动态计算静态字段值 } } ``` #### 四、与实例构造函数的对比 | 特性 | 静态构造函数 | 实例构造函数 | |---------------------|----------------------------|----------------------------| | 调用时机 | 类首次使用前 | 每次实例化对象时 | | 执行次数 | 仅一次 | 每次实例化均执行 | | 访问修饰符 | 不允许 | 允许(如 `public`/`private`)| | 参数 | 禁止 | 允许 | | 初始化目标 | 静态成员 | 实例成员 | #### 五、注意事项 1. **避免实例化实例变量**:静态构造函数中**只能操作静态成员**,不能初始化实例字段。 2. **性能影响**:若静态构造函数包含耗时操作(如I/O),可能导致类首次使用延迟。 3. **隐式生成**:若类包含静态字段但未定义静态构造函数.NET会**自动生成一个空实现**。 : 静态构造函数声明规则 [^3]: 单例模式中的线程安全实现 : 执行时机与初始化顺序 [^5]: 静态成员初始化示例 §§ 相关问题 §§ 1. 静态构造函数与实例构造函数执行顺序是怎样的? 2. 如何在静态构造函数中处理异常? 3. 静态构造函数是否会影响类的序列化? 4. 为什么静态构造函数不能用于依赖注入场景?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值