


























咋看下,两者是没什么不同,其实确实有很大的不同点,readonly的好处,可以控制版本的更新,const关键词定义的是常量,是在编译的时候嵌入到程序里,而readonly 定义的是变量,但是这个变量却有于常量相同的用法而已,一旦初始化后,就不能改变!下面,我们利用ILDASM工具分析一下。
程序清单:
using System;
class CunMang
{
//只定义2个域
public static readonly int x=5;
public const int y=4;
}
class main
{
static void Main(string[]args)
{
//输出
Console.WriteLine(CunMang.x);
Console.WriteLine(CunMang.y);
}
}
OK,编译一下,打开ILDASM:

我们先来看一下,CunMang类中,是如何定义的:

哈,看到了没,readonly在编译的时候是没有赋值的,但用const,在编译的时候就已经赋值了,具体怎么赋值的,我们看一下x,y各自的构造器:
先看下x的:

分析下:
IL_0000: ldc.i4.5 首先在堆栈创建4字节(32位的)的空间,
IL_0001: stsfld int32 CunMang::x 然后把把这个地址引用给x,但是,只有在运行的时候,把这个堆栈最高位(最后赋的值)给x
IL_0006: ret 返回
再看一下y的:

分析下:
IL_0000: ldarg.0 .0意思就是第一个参数,就是直接运算(也许不恰当)y 就是call
IL_0001: call instance void [mscorlib]System.Object::.ctor() 调用这个构造器直接进行赋值了
IL_0006: ret 返回
综上诉:我们可以看出,readonly 是变量类型的,const是常量类型的,readonly 是在运行的时候初始化,也就是在Main();里,但const就编译时就把值嵌入到程序里了
好,下面,我们看下Main() ,程序执行入口里的代码。清单如下:

分析下:
IL_0000: ldsfld int32 CunMang::x
IL_0005: call void [mscorlib]System.Console::WriteLine(int32)
IL_000a: ldc.i4.4
IL_000b: call void [mscorlib]System.Console::WriteLine(int32)
IL_0010: ret
―――――――――――――
IL_0000: ldsfld int32 CunMang::x //看到了吧,当你执行这个程序的时候,就是执行Main()的时候,把这个堆栈的值给x,本来的代码是
IL_0000: ldc.i4.5 ,IL_0001: stsfld int32 CunMang::x 看上面x的构造器,由于构造器(相当于构造函数一样的功能),已经把这个地址引用给x了
所以,在Main()里,直接使用x的引用。
―――――――――――――
IL_0005: call void [mscorlib]System.Console::WriteLine(int32) 下面,执行了这个显示,并输出
―――――――――――――
由于y的值已经被y的构造器(.ctor)赋值了,所以把这个值压入堆栈,下面就执行这个显示,并输出!
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。