c# readonly 和 const的区别和使用场景
文章目录
- **1. 基本概念**
- **`const`**
- **`readonly`**
- **2. 主要区别**
- **3. 使用场景**
- **`const` 的使用场景**
- **`readonly` 的使用场景**
- **4. 示例对比**
- **`const` 示例**
- **`readonly` 示例**
- **5. 注意事项**
- **6. 总结**
在 C# 中,
readonly
和
const
都用于定义不可修改的值,但它们的行为和使用场景有显著的区别。
1. 基本概念
const
- 定义:
const
是一个编译时常量,必须在声明时赋值,且值在编译时确定。 - 作用范围:
const
是静态的,属于类级别,而不是实例级别。 - 内存分配:
const
的值会被直接嵌入到代码中,不占用运行时内存。
readonly
- 定义:
readonly
是一个运行时常量,可以在声明时或构造函数中赋值,值在运行时确定。 - 作用范围:
readonly
可以是实例级别或静态级别。 - 内存分配:
readonly
的值在运行时分配内存。
2. 主要区别
特性 | const | readonly |
---|---|---|
赋值时机 | 必须在声明时赋值 | 可以在声明时或构造函数中赋值 |
作用范围 | 静态(类级别) | 可以是实例级别或静态级别 |
内存分配 | 编译时嵌入代码,不占用运行时内存 | 运行时分配内存 |
数据类型支持 | 仅支持基本类型(如 int 、string 等) | 支持所有数据类型(包括引用类型) |
性能 | 更高(编译时确定) | 较低(运行时确定) |
跨程序集引用 | 值直接嵌入引用程序集 | 值在运行时确定,引用程序集需要重新编译 |
3. 使用场景
const
的使用场景
- 编译时常量:当值在编译时已知且不会改变时,使用
const
。例如数学常数、配置值等。 - 性能优化:由于
const
的值在编译时嵌入代码,访问速度更快。 - 跨程序集引用:如果需要在多个程序集中共享一个常量值,且该值不会改变,可以使用
const
。
public class MathConstants
{
public const double Pi = 3.14159;
public const int MaxRetryCount = 3;
}
readonly
的使用场景
- 运行时常量:当值在运行时才能确定时,使用
readonly
。例如从配置文件或构造函数中获取的值。 - 实例级别的不可变性:当每个实例需要不同的初始值时,使用
readonly
。 - 复杂数据类型:当需要定义不可变的引用类型(如数组、对象)时,使用
readonly
。
public class AppSettings
{
public readonly string ApiKey;
public AppSettings(string apiKey)
{
ApiKey = apiKey; // 在构造函数中赋值
}
}
4. 示例对比
const
示例
public class Constants
{
public const int MaxUsers = 100; // 编译时常量
}
// 使用
int maxUsers = Constants.MaxUsers; // 直接嵌入代码
readonly
示例
public class Configuration
{
public readonly string ConnectionString;
public Configuration(string connectionString)
{
ConnectionString = connectionString; // 在构造函数中赋值
}
}
// 使用
var config = new Configuration("Server=myServer;Database=myDB;");
string connectionString = config.ConnectionString;
5. 注意事项
const
的限制:- 只能用于基本类型(如
int
、double
、string
等)。 - 值必须在声明时确定,不能在运行时计算。
- 只能用于基本类型(如
readonly
的灵活性:- 可以在构造函数中赋值,适合需要运行时初始化的场景。
- 可以用于引用类型(如数组、对象),但引用类型的内容仍然可以修改。
6. 总结
特性 | const | readonly |
---|---|---|
适用场景 | 编译时常量、性能优化、跨程序集引用 | 运行时常量、实例级别不可变性、复杂数据类型 |
赋值时机 | 声明时 | 声明时或构造函数中 |
数据类型支持 | 基本类型 | 所有数据类型 |
性能 | 更高 | 较低 |
根据具体需求选择合适的修饰符:
- 如果值是固定的且在编译时已知,使用
const
。 - 如果值需要在运行时确定或需要实例级别的不可变性,使用
readonly
。