const
和 readonly
在 C# 中有什么区别?
在什么情况下会使用其中一个而不是另一个?
另一个需要注意的地方是,由于const只适用于基本数据类型,如果你想使用类,则可能会感到“被迫”使用ReadOnly。但是,请注意陷阱!ReadOnly意味着您不能将对象替换为另一个对象(无法使其引用另一个对象)。但是,任何持有对象引用的进程都可以自由地修改对象内部的值!
因此,请不要被误导认为ReadOnly意味着用户无法更改事物。据我所知,在C#中没有简单的语法可以防止实例化的类的内部值被更改。
const和readonly有相似之处,但它们并不完全相同。const字段是编译时常量,意味着该值可以在编译时计算。readonly字段允许在类型构造期间运行某些代码的其他场景。构造完成后,readonly字段不能被更改。
例如,const成员可用于定义如下成员:
struct Test
{
public const double Pi = 3.14;
public const int Zero = 0;
}
由于像3.14和0这样的值是编译时常量。然而,考虑一种情况,您定义了一个类型并希望提供一些预制实例。例如,您可能希望定义一个Color类并为常见颜色(如Black、White等)提供“常量”。使用const成员无法实现此目的,因为右侧不是编译时常量。可以使用常规静态成员来实现:
public class Color
{
public static Color Black = new Color(0, 0, 0);
public static Color White = new Color(255, 255, 255);
public static Color Red = new Color(255, 0, 0);
public static Color Green = new Color(0, 255, 0);
public static Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}
但是,如果没有只读特性,客户端可能会更改颜色值,比如交换黑白值。显然,这将会给Color类的其他客户端带来困扰。只读特性解决了这个问题。通过在声明中引入readonly关键字,我们保留了灵活的初始化方式,同时防止客户端代码进行更改。
public class Color
{
public static readonly Color Black = new Color(0, 0, 0);
public static readonly Color White = new Color(255, 255, 255);
public static readonly Color Red = new Color(255, 0, 0);
public static readonly Color Green = new Color(0, 255, 0);
public static readonly Color Blue = new Color(0, 0, 255);
private byte red, green, blue;
public Color(byte r, byte g, byte b) {
red = r;
green = g;
blue = b;
}
}
有趣的是,const成员始终是静态的,而只读成员可以是静态的或非静态的,就像常规字段一样。
这两个目的可以使用一个关键字来实现,但这会导致版本问题或性能问题。暂时假设我们使用一个关键字(const),并且开发人员编写了以下代码:
public class A
{
public static const C = 0;
}
另一位开发者编写了依赖于A的代码:
public class B
{
static void Main() {
Console.WriteLine(A.C);
}
}
ReadOnly:该值只会在类的构造函数中被初始化一次。
const:可以在任何函数中初始化,但只能初始化一次。
常量将被编译为字面值,而静态字符串将作为对所定义的值的引用。
作为练习,尝试创建一个外部库并在控制台应用程序中使用它,然后更改库中的值并重新编译它(不需要重新编译使用者程序),将DLL放入目录中并手动运行EXE,您会发现常量字符串没有改变。
通常情况下,您可以在运行时将静态只读字段分配给非常量值,而常量必须分配一个常量值。
Const: 应用程序生命周期内的绝对常量值。
Readonly: 可以在运行时更改。
关键区别在于Const是C语言中#DEFINE的等效物。数字字面上被替换为预编译器。Readonly实际上被视为变量。
当您的项目A依赖于项目B的公共常量时,这种区别尤其重要。假设公共常量发生了更改。现在您选择const/readonly将影响项目A的行为:
Const:除非使用新的const重新编译,否则项目A不会捕获新值,因为它是使用常量替换编译的。
ReadOnly:项目A将始终请求项目B的变量值,因此它将获取B中公共常量的新值。
老实说,我建议您几乎在所有情况下都使用readonly,除了真正通用的常量(例如Pi,Inches_To_Centimeters)。对于任何可能更改的内容,我建议使用readonly。
希望这有所帮助, 艾伦。
只读字段的值可以被更改。但是,常量字段的值不能被更改。
在只读字段中,我们可以在声明时或该类的构造函数中分配值。对于常量,我们只能在声明时分配值。
只读可以与静态修饰符一起使用,但常量不能与静态修饰符一起使用。
readonly
修饰符与static
修饰符一起使用,但是constant
不能与static
一起使用。这是因为const
字段已经隐式地是静态的。 - undefined