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