const int a

  • must be initialized
  • initialization must be at compile time

readonly int a

  • can use default value, without initializing
  • initialization can be at run time

二者本质的区别在于,const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值。而static readonly是在运行时计算出其值的,所以还可以通过静态构造函数来赋值。 明白了这个本质区别,我们就不难看出下面的语句中static readonly和const能否互换了:

1. static readonly MyClass myins = new MyClass();
2. static readonly MyClass myins = null;
3. static readonly A = B * 20;
static readonly B = 10;
4. static readonly int [] constIntArray = new int[] {1, 2, 3};
5. void SomeFunction()
{
const int a = 10;
...
}

1:不可以换成const。new操作符是需要执行构造函数的,所以无法在编译期间确定 2:可以换成const。我们也看到,Reference类型的常量(除了String)只能是Null。 3:可以换成const。我们可以在编译期间很明确的说,A等于200。 4:不可以换成const。道理和1是一样的,虽然看起来1,2,3的数组的确就是一个常量。 5:不可以换成readonly,readonly只能用来修饰类的field,不能修饰局部变量,也不能修饰property等其他类成员。

因此,对于那些本质上应该是常量,但是却无法使用const来声明的地方,可以使用static readonly。

例如C#规范中给出的例子:

 1 public class Color
2 {
3 public static readonly Color Black = new Color(0, 0, 0);
4 public static readonly Color White = new Color(255, 255, 255);
5 public static readonly Color Red = new Color(255, 0, 0);
6 public static readonly Color Green = new Color(0, 255, 0);
7 public static readonly Color Blue = new Color(0, 0, 255);
8
9 private byte red, green, blue;
10
11 public Color(byte r, byte g, byte b)
12 {
13 red = r;
14 green = g;
15 blue = b;
16 }
17 }

static readonly需要注意的一个问题是,对于一个static readonly的Reference类型,只是被限定不能进行赋值(写)操作而已。而对其成员的读写仍然是不受限制的。 public static readonly MyClass myins = new MyClass(); … myins.SomeProperty = 10;  //正常 myins = new MyClass();    //出错,该对象是只读的

但是,如果上例中的MyClass不是一个class而是一个struct,那么后面的两个语句就都会出错。

Const 和 static readonly的区别:
      可能通过上述纯概念性的讲解,对有些初学者有些晕乎。下面就一些例子来说明下:

 1 using System;
2 class P
3 {
4 static readonly int A=B*10;
5 static readonly int B=10;
6 public static void Main(string[] args)
7 {
8 Console.WriteLine("A is {0},B is {1} ",A,B);
9 }
10 }

对于上述代码,输出结果是多少?很多人会认为是A is 100,B is 10吧!其实,正确的输出结果是A is 0,B is 10。

好吧,如果改成下面的话:using System;

 1 class P
2 {
3 const int A=B*10;
4 const int B=10;
5 public static void Main(string[] args)
6 {
7 Console.WriteLine("A is {0},B is {1} ",A,B);
8 }
9
10 }

对于上述代码,输出结果又是多少呢?难道是A is 0,B is 10?其实又错了,这次正确的输出结果是A is 100,B is
那么为什么是这样的呢?其实在上面说了,const是静态常量,所以在编译的时候就将A与B的值确定下来了(即B变量时10,而A=B*10=10*10=100),那么Main函数中的输出当然是A is 100,B is 10啦。而static readonly则是动态常量,变量的值在编译期间不予以解析,所以开始都是默认值,像A与B都是int类型,故都是0。而在程序执行到A=B*10;所以A=0*10=0,程序接着执行到B=10这句时候,才会真正的B的初值10赋给B。

(C#) What is the difference between "const" and "static readonly" ?的更多相关文章

  1. 到底是 const 还是 static readonly

    真的一样? const 和 static readonly 常在程序中用来声明常量,调用方法也没有什么不同,他们真的一样吗?我们可以做个试验. 程序集内的常量 现在我们建立一个程序,里面有一个MyCl ...

  2. 【转】const和static readonly

    我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等.在多数情况下可以混用.二者本质的区别在于,const的值是在编译期间确定的,因此只能在声 ...

  3. const 还是 static readonly

    到底是 const 还是 static readonly   真的一样? const 和 static readonly 常在程序中用来声明常量,调用方法也没有什么不同,他们真的一样吗?我们可以做个试 ...

  4. const和static readonly的区别

    我们都知道,const和static readonly的确很像:通过类名而不是对象名进行访问,在程序中只读等等. 在多数情况下可以混用.二者本质的区别在于,const的值是在编译期间确定的,因此只能在 ...

  5. C# const和static readonly区别

    [转]C# const和static readonly区别 以前只是知道Const和static readonlyd的区别在于const的值是在编译期间确定的,而static readonly是在运行 ...

  6. Unity C# const与static readonly的区别与联系

    using System; namespace Test { class MainClass { //懒人写法的单例 class Weapon { public static readonly Wea ...

  7. const和static readonly 区别

    const的值是在编译期间确定的,因此只能在声明时通过常量表达式指定其值. 而static readonly是在运行时计算出其值的,所以还可以通过静态构造函数来赋值. static readonly ...

  8. c#中const、static、readonly的区别

    1. const与readonly const ,其修饰的字段只能在自身声明时初始化. Readonly 是只读变量,属于运行时变量,可以在类初始化的时候改变它的值.该类型的字段,可以在声明或构造函数 ...

  9. static, readonly, const

    static Use the static modifier to declare a static member, which belongs to the type itself rather t ...

随机推荐

  1. SQL参数化查询--最有效可预防SQL注入攻击的防御方式

    参数化查询(Parameterized Query 或 Parameterized Statement)是访问数据库时,在需要填入数值或数据的地方,使用参数 (Parameter) 来给值. 在使用参 ...

  2. Apache运行模式

    Apache 2.X 支持插入式并行处理模块,称为多路处理模块(MPM: Multi-Processing Modules).在编译apache时必须选择也只能选择一个MPM,对类UNIX系统,有几个 ...

  3. C# 控件缩写大全+命名规范+示例

    如有转载,请注明出处:http://www.cnblogs.com/flydoos/archive/2011/08/29/2158903.html C# 控件缩写大全+命名规范+示例 写程序的时候突然 ...

  4. ARM1138@PWM例程分析

    1. Buzzer例程控制原理 由ARM1138原理图可得:Buzzer使用CCP3(对应GPIO-G组0x40026000,4号引脚0x00000010)作为输入引脚: Buzzer例程结构: 涉及 ...

  5. Debugging a Parallel Application

    Walkthrough: Debugging a Parallel Application https://msdn.microsoft.com/en-us/library/dd554943.aspx ...

  6. MySQL-负载很高排查思路

    工欲善其事必先利其器,我说一下思路 思路:1.确定高负载的类型 htop,dstat命令看负载高是CPU还是IO2.监控具体的sql语句,是insert update 还是 delete导致高负载3. ...

  7. centos6.4 网络适配器设置仅主机模式

    网络适配器设置仅主机模式时: 1.vmnet1网卡必须开启

  8. jquery得到iframe src属性值的方法

    这篇文章主要介绍了jquery得到iframe src属性值的方法,很简单,很实用,需要的朋友可以参考下 取得iframe src属性的的值: Html代码 <!DOCTYPE HTML> ...

  9. asterisk

    http://www.asterisk.org/ asterisk is the world's most widely adopted open source commnuctions platfo ...

  10. ubuntu12.04+hadoop2.2.0+zookeeper3.4.5+hbase0.96.2+hive0.13.1伪分布式环境部署

    目录: 一.hadoop2.2.0.zookeeper3.4.5.hbase0.96.2.hive0.13.1都是什么? 二.这些软件在哪里下载? 三.如何安装 1.安装JDK 2.用parallel ...