在声明字段时,可以使用readonly关键字声明一个动态常量。readonly 关键字不同于 const 关键字。 const 字段只能在该字段的声明中初始化。 可以在字段声明和任何构造函数中多次分配 readonly 字段的值。 因此,根据所使用的构造函数,readonly 字段可能具有不同的值。但是,采用readonly修饰的字段或变量,也仅仅在声明时赋值或构造函数中赋值这两种途径。
使用格式
readonly 数据类型 字段名/变量量 = 值;
观察下面的例子
public class Math
{
public readonly double PI = 0;
public Math()
{
PI = 3.1415926;
}
void Change()
{
PI = 0;
/* 错误:无法分配到只读字段
* (除非在定义了该字段的类型的构造函数
* 或 init-only 资源库中,
* 或者在变量初始值设定项中)
*/
}
}
我们在类型Math中声明了一个只读字段PI,同时赋值为0,然后在构造函数中将PI的值改成3.1415926,这都是合法的。最后,在Change成员中再次将PI改成0时,编译器会引发一个错误,导致源代码无法编译。这个错误的提示就是:CS0191 无法分配到只读字段(除非在定义了该字段的类型的构造函数或 init-only 资源库中,或者在变量初始值设定项中)。
所以,readonly修饰的字段,只有两种途径可以赋值。
另外,如果将PI定义成一个静态只读的字段,这个连构造函数中都不能修改其值,否则将引发如下错误:CS0198 无法对静态只读字段赋值(静态构造函数或变量初始值中除外)。除非在静态构造函数中去修改值。
正确的做法如下:
public class Math
{
public static readonly double PI = 0; //静态字段
static Math() //静态构造函数
{
PI = 3.1415926;
}
}
internal class Program
{
static void Main(string[] args)
{
Console.WriteLine($"PI = {Math.PI}");
Console.ReadKey();
}
}
输出结果
PI = 3.1415926
总结如下
项目 | const静态常量 | readonly动态常量 |
定义 | 声明的同时要设置常量值。 | 声明的时候可以不需要进行设置常量值,可以在类的构造函数中进行设置。 |
类型限制 | 只能修饰基元类型,枚举类型或者字符串类型。 | 没有限制,可以用它定义任何类型的常量。 |
对于类对象而言 | 对于所有类的对象而言,常量的值是一样的。 | 对于类的不同对象而言,常量的值可以是不一样的。 |
内存消耗 | 无 | 要分配内存,保存常量实体。 |
综述 | 性能要略高,无内存开销,但是限制颇多,不灵活。 | 灵活,方便,但是性能略低,且有内存开销。 |
表1 const和readonly的区别
- const修饰的常量在声明的时候必须初始化;readonly修饰的常量则可以延迟到构造函数初始化 。
- const常量既可以声明在类中也可以在函数体内,但是static readonly常量只能声明在类中。
- const是静态常量,所以它本身就是static的,因此不能手动再为const增加一个static修饰符。
- const修饰的常量在编译期间就被解析,即:经过编译器编译后,我们都在代码中引用const变量的地方会用const变量所对应的实际值来代替; readonly修饰的常量则延迟到运行的时候。
当前课程源码下载:(注明:本站所有源代码请按标题搜索)
文件名:047-readonly动态常量.zip
链接:https://pan.baidu.com/s/1Bq2lX7cruUbklLwgjGggSw
提取码:byte
——重庆教主 2024年1月24日