常量:const,readonly
C#常量主要分为两种:
①静态常量(Compile-time constant)/编译时常量
②动态常量(Runtime constant)/运行时常量
一、两者区别:
静态常量/编译时常量,在编译时便用该常量的值代替常量变量。 用 const 修饰
动态常量/运行时常量,在运行时返回一个运行时常量的变量引用。 用readonly 修饰
二、Compile-time constant:
1.在编译时会用其值替换掉所有的编译时常量变量,当你更换程序集时,在引用的程序中,原来编译时常量的值不会改变。(在编译时就已经用值替换了变量)
2.用const定义的常量,对于所有类对象而言都是一样的,因此需要像访问静态成员那样去访问const定义的常量,而用对象的成员方式去访问会出变异错误。
此外,对于静态常量的访问在编译的时候,是用常量的值去替换常量,例如:
int nValue = MAX_VALUE;
这句在编译之后,和如下这句所产生的中间语言代码是一样的。
int nValue = 10;
3.在用const来定义常量的时候,在类型上有很多限制:
首先,此类型必须属于值类型,同时此类型的初始化不能通过new来完成,因此一些用struct定义的值类型常量也不能用const来定义。
三。Runtime constant:
1.运行时保留的是运行时变量的引用,所以会用新的值代替掉原来的值。
2.对于运行时常量,只能在初始化时赋值,或者是构造函数中复制。而不能在其他地方赋值,否则会提示错误。

对于运行时变量,只能在构造函数和初始化时对其赋值。因为我用的运行时变量时静态的,所以错误提示我在静态构造函数中赋值,这没有冲突。
3.为什么称为动态变量?
因为系统要为readonly所定义的常量分配空间,即和类的其他成员一样拥有独立的空间。
此外,readonly所定义的常量除了在定义的时候可以设定常量值外,还可以在类的构造函数中进行设定。
由于readonly所定义的常量相当于类的成员,因此使用const来定义常量所受到的类型限制,在使用readonly去定义的时候全部消失,即可以用readonly去定义任何类型的常量。
四、区别:
区别: | | |
| 静态常量(Compile-time constant) | 动态常量(Runtime constant) |
定义 声明 | 定义 声明的同时要设置常量值。 | 声明的时候可以不需要进行设置常量值,可以在类的构造函数中进行设置。 |
类型限制 | 首先类型必须属于值类型范围,且其值不能通过new来进行设置。 | 没有限制,可以用它定义任何类型的常量。 |
值 | 对于类对象而言 对于所有类的对象而言,常量的值是一样的。 | 对于类的不同对象而言,常量的值可以是不一样的。 |
内存消耗 | 无。 | 要分配内存,保存常量实体。 |
综述 | 性能要略高,无内存开销,但是限制颇多,不灵活。 | 灵活,方便,但是性能略低,且有内存开销。 |
五、ps:
使用const 会出现的bug:
在程序中使用DLL类库某个类的静态常量时,如果在类库中修改静态常量的值,其它接口没有发生变化,一般来说,程序调用端是不需要重新编译,直接执行就可以调用新的类库。
不过就是在此情况下,会产生潜在的bug。这是由于静态常量在编译的时候,是用它的值去替换常量,因此在调用端的程序也是这样进行替换的。
需要回收
六、eg:
1:赋值
1 public class Test()
2 {
3 public const int a=10 ;//静态常量
4 public static readonly int b=11;//动态常量
5 }
1 class Program
2 {
3 static void Main(string[] args)
4 {
5
6 Console.WriteLine(a);
7 Console.WriteLine(b);
8 Console.Read();
9 }
10 }输出:
10
111 public class Test()
2 2 {
3 3 public const int a=100 ;//静态常量
4 4 public static readonly int b=110;//动态常量
5 5 }输出:
10
1102:
1 public class Test
2 {
3 public const int num1=10 ;
4 public static readonly int num2;
5
6 }上述代码 可以 编译通过。
调用时,对常量进行赋值
1 class Program
2 {
3 static void Main(string[] args)
4 {
5 Test.num2= 5;//企图对运行时变量进行赋值
6 Console.WriteLine(Test.num2);
7 Console.Read();
8 }
9 }编译时,会提示错误:

















