目录
一、什么是静态的?什么是常量?
1. 静态(Static)
2. 常量(const)
二、类中的静态成员有什么用?
1. 共享数据
2. 工具方法与全局配置
3. 单例模式
三、静态类和静态成员方法的介绍
1. 静态类(Static Class)
2. 静态构造函数(Static Constructor)
3. 静态方法的限制
四、对比总结
1. 静态成员 vs 常量(const)
2. 静态类 vs 普通类
3. 使用场景
注意事项
前言:代码中的“共享经济”与“不变法则”
有没有想过,如何让一个类的所有实例共享同一份数据?或者怎样创建一种无需实例化就能调用的“工具包”方法?
在C#的世界里,静态成员就像魔法般的全局变量,而常量则是刻在代码石碑上的永恒法则。它们一个灵活善变(但需谨慎),一个坚守初心(绝不妥协)。
本文将揭秘静态类的“禁欲系”设计、静态构造函数的幕后初始化大法,并带你理清静态成员与常量的爱恨纠葛——从此告别重复代码,让你的程序优雅如诗!
一、什么是静态的?什么是常量?
1. 静态(Static)
静态是C#中用于描述类级别成员的关键字。静态成员(如静态字段、方法、属性)属于类本身而非类的实例,所有实例共享同一份静态成员。
- 内存分配:静态成员在程序启动时分配内存,生命周期与应用程序一致。
- 访问方式:直接通过类名访问,无需实例化对象。
记住!!!
程序是不能无中生有的
我们要使用的对象 变量 函数 都是要在内存中分配空间的
之所以要实例化对象 目的就是要分配内存空间,在程序中 产生一个抽象的对象静态成员的特点
程序开始运行时 就会分配内存空间 所以我们可以直接使用
静态成员和程序同生共死
只要使用了他 直到程序结束时 内存空间才会被释放
所以每个静态成员都有属于自己的唯一一个小房间
这让静态成员便有了唯一性
在任何地方使用 都是使用小房间里面的内容 修改的也是房间里面的内容
2. 常量(const)
常量是通过const
关键字定义的不可修改的编译时常量。
- 内存分配:值在编译时确定并嵌入到IL代码中。
- 不可变性:必须在声明时赋值,且只能为基本类型(如
int
,string
)或null
。
// 静态字段 vs 常量
public class Config {public static string Environment = "Production"; // 静态字段(可修改)public const int MaxRetryCount = 3; // 常量(不可修改)
}
const (常量)可以理解为特殊的静态static
相同点:
他们都可以通过类名点出使用
不同点
1.const 必须初始化,不能修改 static 没有这个限制
2.const 只能修饰变量,static可以修饰很多
3.const一定是写在访问修饰符后面的,static没有这个要求
二、类中的静态成员有什么用?
1. 共享数据
静态成员用于存储所有实例共享的数据。例如,统计类的实例总数:
public class User {public static int UserCount = 0; // 所有实例共享public User() {UserCount++;}
}Console.WriteLine(User.UserCount); // 直接通过类访问
2. 工具方法与全局配置
将无需实例化的工具方法或全局配置定义为静态成员:
public class MathUtils {public static double PI = 3.1415926;public static int Add(int a, int b) => a + b;
}
Console.WriteLine(MathUtils.Add(2, 3)); // 直接调用静态方法
3. 单例模式
通过静态成员实现单例(确保类只有一个实例):
public class Singleton {private static Singleton _instance;public static Singleton Instance => _instance ??= new Singleton();private Singleton() { }
}
三、静态类和静态成员方法的介绍
1. 静态类(Static Class)
- 定义:用
static
修饰的类,不能实例化,只能包含静态成员。 - 用途:封装工具类或扩展方法容器。
public static class StringExtensions {public static string ToTitleCase(this string input) {return CultureInfo.CurrentCulture.TextInfo.ToTitleCase(input);}
}string name = "john doe";
Console.WriteLine(name.ToTitleCase()); // 输出 "John Doe"
注意:直接类名然后点出来使用 里面的方法
2. 静态构造函数(Static Constructor)
- 作用:初始化静态字段或执行一次性的静态初始化逻辑。
- 调用时机:在类首次被访问(如创建实例、调用静态方法)时自动执行。
注:这里的创造实例是指的是点出内部已经给你创造好的实例。你自己是无法new的。
看如下代码:
public class Singleton {// 静态成员管理唯一实例private static Singleton _instance;public static Singleton Instance => _instance ??= new Singleton();// 私有构造函数,禁止外部 newprivate Singleton() { }
}// 正确!通过静态属性访问唯一实例
var instance = Singleton.Instance;
这份代码是静态构造函数的一个实际应用:
这段代码定义了一个 Logger
类,其核心功能是初始化日志文件的存储目录。通过静态成员和静态构造函数的设计,确保日志目录在程序运行期间只创建一次,且无需手动初始化。
public class Logger {public static string LogDirectory;static Logger() {LogDirectory = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Logs");Directory.CreateDirectory(LogDirectory);}
}
注意:这个主要是用来初始化,做一些配置什么的
3. 静态方法的限制
- 不能访问实例成员(非静态字段、方法),只能访问其他静态成员。
- 不能使用
this
关键字。
四、对比总结
1. 静态成员 vs 常量(const)
特性 | 静态成员 | 常量(const) |
---|---|---|
内存分配 | 运行时分配 | 编译时嵌入到IL代码 |
可修改性 | 可修改(除非是readonly ) | 不可修改 |
类型限制 | 无限制 | 仅支持基本类型或null |
初始化时机 | 静态构造函数或声明时 | 必须在声明时赋值 |
2. 静态类 vs 普通类
特性 | 静态类 | 普通类 |
---|---|---|
实例化 | 不可实例化 | 可以实例化 |
成员类型 | 仅包含静态成员 | 可包含静态和实例成员 |
继承 | 不能继承或被继承 | 支持继承 |
3. 使用场景
- 静态成员:共享数据、工具方法、全局配置。
- 静态类:工具类、扩展方法容器、单例模式。
- 常量:固定不变的值(如数学常数、配置标志)。
注意事项
- 避免过度使用静态成员:可能导致代码耦合度高、难以测试。
- 线程安全问题:静态成员在多线程环境下需加锁(如
lock
)。- 常量的限制:无法在运行时动态赋值(如从配置文件读取)。
- 静态构造函数的性能:避免在静态构造函数中执行耗时操作。
通过合理使用静态成员和常量,可以显著提升代码的模块化和执行效率,但需谨慎平衡其适用场景!