在 C# 中,const和readonly都用于定义不可变的值
定义与初始化
const:const用于定义编译时常量,在编译时就必须为其赋值,且赋值后在整个程序运行期间都不能再修改。- 只能使用基本数据类型(如
int、double、bool等)、枚举类型或字符串类型来定义常量。 - 必须在声明时就进行初始化,不能在后续代码中再赋值。
- 示例:
cs
public class ExampleClass
{
public const int ConstantValue = 10;
}
readonly:readonly用于定义运行时常量,它可以在声明时初始化,也可以在构造函数中进行初始化。一旦初始化完成,其值就不能再被修改。- 可以是任何数据类型,包括自定义类、结构体等引用类型。
- 示例:
cs
public class ExampleClass
{
public readonly int ReadonlyValue;
public ExampleClass(int value)
{
ReadonlyValue = value;
}
}
内存分配与使用
const:const常量在编译时会被直接替换为其对应的值,因此不会在运行时分配额外的内存空间。例如,当代码中使用const常量时,编译器会将其替换为具体的常量值,而不是通过变量引用。- 示例代码:
cs
const int a = 5;
int result = a + 3; // 编译时,a 会被直接替换为 5
readonly:readonly变量在运行时分配内存空间,其值在初始化后存储在该内存中。每次访问readonly变量时,都会通过该内存地址来获取其值。- 示例代码:
cs
readonly int b = 5;
int result = b + 3; // 运行时通过内存地址访问 b 的值
静态与实例
const:const成员隐式地为静态成员,不能使用static关键字来修饰const常量。可以通过类名直接访问const常量,无需创建类的实例。- 示例:
cs
public class MyClass
{
public const string MyConstant = "Hello";
}
// 直接通过类名访问
string value = MyClass.MyConstant;
readonly:readonly可以是实例成员,也可以是静态成员。当作为实例成员时,每个类的实例都可以有不同的readonly值;当使用static关键字修饰时,它成为静态成员,可通过类名直接访问。- 示例:
cs
public class MyClass
{
public readonly int InstanceReadonly;
public static readonly int StaticReadonly = 20;
public MyClass(int value)
{
InstanceReadonly = value;
}
}
// 实例成员访问
MyClass obj = new MyClass(10);
int instanceValue = obj.InstanceReadonly;
// 静态成员访问
int staticValue = MyClass.StaticReadonly;
继承与多态
const:- 由于
const是编译时常量,在子类中不能重写父类的const成员。如果子类中定义了与父类同名的const常量,它们是完全独立的两个常量。 - 示例:
- 由于
cs
class ParentClass
{
public const int MyConst = 10;
}
class ChildClass : ParentClass
{
public const int MyConst = 20; // 与父类的 MyConst 是不同的常量
}
readonly:- 对于实例
readonly成员,每个实例可以有不同的初始值,表现出一定的灵活性。而静态readonly成员在类的所有实例间共享同一个值。在继承体系中,子类不能重写父类的readonly成员,但可以在子类中定义自己的readonly成员。 - 示例:
- 对于实例
cs
class ParentClass
{
public readonly int MyReadonly = 10;
}
class ChildClass : ParentClass
{
public readonly int MyReadonly = 20; // 子类自己的 readonly 成员
}