const是编译时常量,值在编译时确定且所有实例共享,适用于如PI等固定值;readonly是运行时常量,可在构造函数中初始化,每个实例可不同,适用于创建时间等需运行时赋值的场景。

readonly和
const都是C#中用于声明不可变性的关键字,但它们在编译时和运行时行为以及适用场景上存在显著差异。简单来说,
const是编译时常量,而
readonly是运行时常量。
readonly允许你在运行时初始化,可以用于类成员,并且每个实例可以有不同的值。
const必须在声明时初始化,且其值在编译时确定,所有实例共享相同的值。
C#中的
readonly关键字和
const关键字,虽然都用于表示“不可变”,但它们背后的机制和使用场景却大相径庭。理解这些差异,能让你在编写C#代码时做出更明智的选择。
readonly
与const
:一个编译时,一个运行时
最核心的区别在于,
const是编译时常量,而
readonly是运行时常量。这意味着什么?
-
const
: 编译器会在编译时将const
变量的值直接嵌入到代码中。这有点像宏定义,每次使用const
变量的地方,都会被替换成它的实际值。因此,const
变量必须在声明时就被初始化,并且其值必须是一个可以在编译时确定的常量表达式。public const int MaxValue = 100; // 正确,100是编译时常量 // public const int CurrentTime = DateTime.Now.Hour; // 错误,DateTime.Now.Hour的值在运行时才能确定
-
readonly
:readonly
字段的值可以在运行时初始化,可以在构造函数中赋值。这意味着,每个类的实例可以拥有不同的readonly
字段值。public readonly DateTime CreationTime; public MyClass() { CreationTime = DateTime.Now; // 正确,在构造函数中初始化 }这里,
CreationTime
的值取决于MyClass
实例创建的时间,每个实例的CreationTime
可能都不一样。
何时使用const
?
const适用于那些在编译时就能确定,并且在程序的整个生命周期中都不会改变的值。比如:
- 数学常数:
public const double PI = 3.14159;
- 配置值:
public const string AppName = "MyApplication";
- 枚举的默认值:
public const int DefaultErrorCode = 0;
使用
const的好处是性能更高,因为编译器会直接将值嵌入代码,避免了运行时的查找。但缺点是灵活性较差,一旦修改了
const的值,所有引用它的程序集都需要重新编译。
本文档主要讲述的是Python开发网站指南;HTML是网络的通用语言,一种简单、通用的全置标记语言。它允许网页制作人建立文本与图片相结合的复杂页面,这些页面可以被网上任何其他人浏览到,无论使用的是什么类型的电脑或浏览器 Python和其他程序语言一样,有自身的一套流程控制语句,而且这些语句的语法和其它程序语言类似,都有for, if ,while 类的关键字来表达程序流程。希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
何时使用readonly
?
readonly适用于那些在运行时初始化,或者每个实例可能拥有不同值,但一旦初始化后就不应该再改变的值。比如:
- 对象的创建时间:如上面的
CreationTime
例子。 - 依赖注入的配置:
public readonly ILogger Logger;
(在构造函数中注入) - 只读的计算结果:
public readonly int TotalCount = CalculateTotal();
使用
readonly的优点是灵活性更强,允许在运行时初始化,并且每个实例可以拥有不同的值。缺点是性能略低于
const,因为需要在运行时进行查找。
static readonly
:一个特殊的组合
static readonly组合表示一个静态字段,它只会被初始化一次,并且在整个应用程序的生命周期中保持不变。这通常用于存储一些需要在类级别共享,但又需要在运行时初始化的值。
public static readonly string AppVersion = GetAppVersion();
private static string GetAppVersion() {
// 从配置文件或数据库中读取版本号
return "1.2.3";
}在这个例子中,
AppVersion在应用程序启动时会被初始化一次,然后所有
MyClass的实例都可以访问到这个版本号。
值类型 vs 引用类型:readonly
行为的微妙之处
需要注意的是,
readonly只能保证字段本身的值不可变,但如果字段是引用类型,
readonly只能保证引用不可变,而不能保证引用指向的对象的内容不可变。
public readonly ListItems = new List (); public void AddItem(string item) { Items.Add(item); // 这是允许的,因为Items指向的List对象的内容可以改变 }
如果想要保证引用类型的内容也不可变,可以使用不可变集合,比如
ImmutableList。
总结
选择
const还是
readonly,取决于你的具体需求。如果值在编译时就能确定,并且在程序的整个生命周期中都不会改变,那么
const是更好的选择。如果值需要在运行时初始化,或者每个实例可能拥有不同的值,那么
readonly更合适。理解这些差异,能让你编写出更健壮、更灵活的代码。







