C#中const和readonly的区别

C#中const和readonly的区别

技术背景

在C#编程中,constreadonly都用于定义不可变的值,但它们在使用方式、编译处理和应用场景上存在差异。了解这些差异对于编写高质量、可维护的C#代码至关重要。

实现步骤

1. const的使用

const关键字用于定义编译时常量,这些常量的值在编译时就已确定,并且在程序运行期间不能更改。常量必须在声明时进行初始化,且只能使用常量表达式。

1
2
3
4
public class MyClass
{
public const double PI1 = 3.14159;
}

2. readonly的使用

readonly关键字用于定义只读字段,这些字段的值可以在声明时初始化,也可以在构造函数中初始化。一旦初始化,其值在对象的生命周期内不能更改。

1
2
3
4
5
6
7
8
9
10
public class MyClass1
{
public readonly double PI2 = 3.14159;
public readonly double PI3;

public MyClass1()
{
PI3 = 3.14159;
}
}

核心代码

const示例

1
2
3
4
5
6
7
8
9
10
public class Const_V_Readonly
{
public const int I_CONST_VALUE = 2;
public readonly int I_RO_VALUE;

public Const_V_Readonly()
{
I_RO_VALUE = 3;
}
}

readonly示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class Sample
{
private readonly string ro;

public Sample()
{
ro = "set";
}

public Sample(string value) : this()
{
ro = value;
}
}

最佳实践

使用const的场景

当你确定某个值在整个应用程序生命周期内都不会改变时,使用const。例如,数学常量、单位换算系数等。

1
public const int CM_IN_A_METER = 100;

使用readonly的场景

当某个值可能会根据不同的条件或配置而改变,但在对象创建后不需要再次修改时,使用readonly。例如,数据库连接字符串、配置文件中的参数等。

1
2
3
4
5
6
public readonly string ConnectionString;

public MyClass(string connectionString)
{
ConnectionString = connectionString;
}

常见问题

1. DLL版本问题

如果在一个程序集中使用了另一个程序集中的const常量,当该常量的值发生变化时,使用该常量的程序集必须重新编译才能获取新值。而readonly字段不存在这个问题,因为其值是在运行时获取的。

2. 引用类型问题

对于引用类型,readonly只保证引用本身不可变,而不保证引用对象的内容不可变。例如:

1
2
3
4
5
6
7
8
9
10
public class Const_V_Readonly
{
public readonly char[] I_RO_VALUE = new Char[] { 'a', 'b', 'c' };

public void UpdateReadonly()
{
I_RO_VALUE[0] = 'V'; // 合法,可修改引用对象的内容
I_RO_VALUE = new char[] { 'V' }; // 编译错误,不能更改引用本身
}
}

3. 反射修改问题

readonly字段的值可以通过反射进行修改,这在某些情况下可能会导致意外的结果。例如:

1
2
3
4
5
var fi = this.GetType()
.BaseType
.GetField("_someField",
BindingFlags.Instance | BindingFlags.NonPublic);
fi.SetValue(this, 1);

综上所述,constreadonly虽然都用于定义不可变的值,但它们的使用场景和行为有所不同。在实际编程中,需要根据具体需求选择合适的关键字。


C#中const和readonly的区别
https://119291.xyz/posts/difference-between-const-and-readonly-in-csharp/
作者
ww
发布于
2025年5月27日
许可协议