.NET中,const和readonly区别
在.NET中,const和readonly都用于定义不可变的值,但它们在行为和使用场景上有显著区别。以下是两者的详细对比:
- 初始化时机
• const
◦ 编译时常量,必须在声明时赋值。
◦ 值在编译时确定,并被直接嵌入到IL代码中(类似字面量)。
◦ 示例:
csharp
public const int MaxValue = 100; // 必须直接赋值
• readonly
◦ 运行时常量,可以在声明时或构造函数中赋值。
◦ 值在运行时确定(如根据配置或逻辑动态计算)。
◦ 示例:
csharp
public readonly int MaxValue;
public MyClass(int value) {
MaxValue
= value; // 允许在构造函数中赋值
}
- 类型限制
• const
◦ 仅支持基元类型(如int、bool、string)或null引用。
◦ 不支持复杂类型(如对象、数组、DateTime)。
◦ 示例:
csharp
public const string Name = “C#”; // 合法
public const DateTime Date = default; // 编译错误(非基元类型)
• readonly
◦ 支持任意类型,包括对象、集合、自定义类等。
◦ 示例:
csharp
public readonly List Numbers = new List();
public readonly DateTime CreatedAt;
- 作用域
• const
◦ 隐式静态(static),属于类级别,所有实例共享同一个值。
◦ 访问方式:ClassName.ConstName。
◦ 示例:
csharp
Console.WriteLine(MyClass.MaxValue); // 直接通过类名访问
• readonly
◦ 默认为实例级别,每个对象可拥有不同的值。
◦ 也可声明为static readonly,此时为类级别。
◦ 示例:
csharp
public class MyClass {
public readonly int InstanceValue;
public static readonly int StaticValue = 42;
}
-
内存分配
• const
◦ 值被编译到IL中,不占用实际内存空间(类似于字面量)。
◦ 修改后需重新编译所有依赖的程序集。
• readonly
◦ 作为字段存储在内存中,每个实例或类有独立存储。
◦ 修改后仅需重新编译当前程序集。 -
版本控制
• const
◦ 若修改const值,引用它的其他程序集必须重新编译,否则继续使用旧值(硬编码到IL中)。
◦ 易引发版本不一致问题。
• readonly
◦ 修改后,依赖程序集无需重新编译即可获取新值(运行时解析)。 -
适用场景
• const
◦ 数学常数、固定字符串等无需修改的全局值。
◦ 示例:
csharp
public const double Pi = 3.14159;
public const string AppName = “MyApp”;
• readonly
◦ 需运行时计算的配置值或对象。
◦ 示例:
csharp
public readonly string ConnectionString;
public readonly Lazy _data = new Lazy(LoadData);
通过合理选择const和readonly,可以提升代码的灵活性、可维护性和性能。