我读《Microsoft .NET框架程序设计(修订版)》------DoItNow的读书笔记7 也谈const VS readonly

这个问题前些天 与很多人都讨论过. 其中吴海鹏的结论是 const定义的常量是属于类型的 而readonly定义的只读变量是属于 实例的. "框架编程"则本书上 也有对此问题的 说明. 下面我将通过代码 及其编译后的IL 阐述一些这个问题.
namespace xieran.Test
{
    
public class myClass
    
{
        
const string myName= "Liuxd";
        
private readonly string myScholl="QDU";

        
static public void Main(System.String[] args)
        
{
            System.Console.WriteLine(
"Hi,Mr.Liuxd!");
            System.Console.ReadLine();
        }

    }

}

当把上面的代码编译后 查看MSIL

可以看到定义为const的myName在IL中变成了一个static的字符串了, 静态的东西是属于类型的.而定义为readonly的myScholl是属于对象的 (吴海鹏说的是正确的:))

在上面的代码中 我在加一句 静态的变量myGame如下:
namespace xieran.Test
{
    
public class myClass
    
{
        
const string myName= "Liuxd";
        
static string myGame= "footBall";
        
private readonly string myScholl="QDU";

        
static public void Main(System.String[] args)
        
{
            System.Console.WriteLine(
"Hi,Mr.Liuxd!");
            System.Console.ReadLine();
        }

    }

}

在看编译后的MSIL的情况

可以看到除了增加了一个静态的变量myGame外,csc编译器还自动增加了一个类型构造器(.cctor---class constructor). 打开此类型构造器看到IL如下:

.method private hidebysig specialname rtspecialname static
        void  .cctor() cil managed
{
  // 代码大小       11 (0xb)
  .maxstack  1
  IL_0000:  ldstr      "footBall"
  IL_0005:  stsfld     string xieran.Test.myClass::myGame
  IL_000a:  ret
} // end of method myClass::.cctor

也就是说在代码中声明的静态字段 是在类型构造器中初始化的, 声明的const显然没有在类型构造器中初始化.

在myName上双击打开其代码 为
.field private static literal string myName = "Liuxd"
在myGame上打开其代码为
.field private static string myGame
也就是说常量是在编译时确定其值的. 各种变量(包括static变量)是在运行时 通过构造器(实例构造器或类型构造器)进行初始化的. 常量在编译后其值是放在模块的元数据中的. 同时由于常数是在编译时初始化,所有其 能够支持的数据类型也是有限的(其类型必须是编译器认识的“基元类型“如Int32,String等,至于其他的各种类型就不支持了).

 

posted on 2004-07-02 12:41  追忆似水年华  阅读(1865)  评论(6编辑  收藏  举报

导航