C# 静态常量(const)动态常量(static、readonly)用法区别
思维导图
常量的命名方法
带有 private 私有访问修饰符的常量要以骆驼命名法命名,即以下划线开头,第一个单词的首字母小写,余下单词首字母大写。
private const string _bookName = "新华字典";
带有 public 公共修饰符、protected 受保护修饰符等的常量要以帕斯卡命名法命名,即各个单词首字母都要大写。
public const int BookPrice = 10;
一个低级错误
错误原因:函数体内变量只能是局部变量,不能加访问修饰符(低级错误)
readonly、const
代码
class MyConst
{
public static readonly int A = 2; //A为运行时常量
public const int B = 3; //B为编译时常量
}
public static void Main(string[] args)
{
int C = MyConst.A+MyConst.B;
Console.WriteLine(C);
}
其中的const常量B被替换成字面量3,而readonly常量A则保持引用方式
int C = MyConst.A+MyConst.B;
将编译为
int C = MyConst.A+3;
使用方式
readonly常量只能声明为类字段,支持实例类型或静态类型,可以在声明的同时初始化或者在构造函数中初始化,初始化完成后便无法更改。
const常量除了可以声明为类字段之外,还可以声明为方法中的局部常量,默认为静态类型(无需用static修饰,否则将导致编译错误),但必须在声明的同时完成初始化。
支持类型
const常量在编译时将被替换为字面量,使得其取值类型受到了一定限制。const常量只能被赋予数字(整数、浮点数)、字符串以及枚举类型。下面的代码无法通过编译
public const DateTime D = DateTime.MinValue;
改成readonly就可以正常编译
public readonly DateTime D = DateTime.MinValue;
维护性
readonly 以引用方式进行工作,某个常量更新后,所有引用该常量的地方均能得到更新后的值。
const 跨程序集调用时,如果在程序集修改了常量的值,另一个程序集需要重新编译才能生效
性能比较
const直接以字面量形式参与运算,性能要略高于readonly,但对于一般应用而言,这种性能上的差别可以说是微乎其微。
优先使用
- 取值永久不变(比如圆周率、一天包含的小时数、地球的半径等)
- 对程序性能要求非常苛刻
可以使用const常量,除此之外的其他情况都应该优先采用readonly常量。
C# Static 与 Java Static
两者用法完全是一致的
- 变量是属于类的,不是实例级别的。只能通过类名调用,不能通过实例调用。
- 如果在定义时就赋值了,那么在类初始化的时候,最先完成所有静态变量的赋值。但是要注意,所有静态变量的初始化顺序是无法确定的。
C# Const 与 Java Final
作用
变量(声明时或者构造函数)初始化后不能更改
修饰变量
C#中的const 等价于 Java中的static final,也就是说,Java中final不具有static的功能。而C#中的const具有static的功能。因此在C#中 public static const string
等价于 public const string
。
修饰类和方法
此时Java中的final类似C#中的sealed,就是说,final修饰的类不能被继承,final修饰的方法不能被覆盖。
而C#中的const不能修饰类和方法。
私有静态成员的作用(private static 变量)
字面表示私有的,类外不能使用;静态的,全局变量。看上去很矛盾,又不能被类外使用,要全局的有什么用?问得好,类中全局也是很有意义的,例如 private static int a = 5,那么就可以保证变量a在类的初始化过程中将被优先初始化(在构造函数执行之前)。
这样如果对象A的初始化需要对象B的实例,那么就可以用这种声明,以保证在类A在构造函数中能够使用类B的实例。
同时private又能够保证类B的实例只能在类A中使用,起到很好的密封作用。
私有最终成员作用(private final 变量)
在类构造函数完成前必须对该成员完成初始化,一旦定义不许更改;该成员只能在本类中使用。实例,子类中都不能使用。
private static final
修饰的成员在声明时就被赋值,保证在构造函数中可以被使用,一个被private static final
修饰的成员通常表示其他组件的一个实例,且变量是类中的全局变量。
private final
修饰的成员在构造中被赋值,表示它是该类全局的私有成员变量,且该类的构造需要传入他们的初始值,才能完成类的初始化。