Const是在编译的时候为其赋值,一旦赋值其值永远都不能改变。声明成const 类型的变量必须在声明的同时为其赋值,这样编译器在编译的时候就计算其具体“值”。正是因为这样的原因const类型的数据类型应该是简单数据类型或String类型。因为在引用类型中除了String类型外其它的引用类型都不能在编译的时候获取其准确值(null除外)。而static readonly 是在运行时为其赋值,所以其类型可以是值类型也可以是引用类型。static readonly类型的变量只有两种途径为其赋值,在声明该变量的时候或在默认的静态构造函数里面为其赋值。实际上这两种方法最后生成的IL代码是相同的(都是在静态构造函数中赋值)。值得注意的是,当static readonly类型变量是引用类型时,在当前类中此变量虽然不能再进行new 操作分配空间,但是可以更改此变量内的field的值。
如下面代码:
1using System;
2
3namespace ConsoleApplication1
4{
5 public class User
6 {
7
8 public string userName ;
9 public int userID;
10 }
11 /// <summary>
12 /// Class1 的摘要说明。
13 /// </summary>
14 class Class1
15 {
16 public static readonly User user;
17 public static readonly int i = 12;
18 static Class1()
19 {
20 user = new User();
21 }
22
23 /// <summary>
24 /// 应用程序的主入口点。
25 /// </summary>
26 [STAThread]
27 static void Main(string[] args)
28 {
29 //
30 // TODO: 在此处添加代码以启动应用程序
31 //
32 user.userName= "jjj";//这里是允许修改的
33 user.userID = 13;
34 Console.Write(user.userName);
35 //user = new User(); 不能编译通过
36
37
38 }
39
40 }
41}
42
2
3namespace ConsoleApplication1
4{
5 public class User
6 {
7
8 public string userName ;
9 public int userID;
10 }
11 /// <summary>
12 /// Class1 的摘要说明。
13 /// </summary>
14 class Class1
15 {
16 public static readonly User user;
17 public static readonly int i = 12;
18 static Class1()
19 {
20 user = new User();
21 }
22
23 /// <summary>
24 /// 应用程序的主入口点。
25 /// </summary>
26 [STAThread]
27 static void Main(string[] args)
28 {
29 //
30 // TODO: 在此处添加代码以启动应用程序
31 //
32 user.userName= "jjj";//这里是允许修改的
33 user.userID = 13;
34 Console.Write(user.userName);
35 //user = new User(); 不能编译通过
36
37
38 }
39
40 }
41}
42
如果把类User换成结构体的话,user.username = “jjj”这行就不能通过编译了。