总结一下const和readonly
- const和readonly的值一旦初始化则都不再可以改写;
- const只能在声明时初始化;readonly既可以在声明时初始化也可以在构造器中初始化;
- const隐含static,不可以再写static const;readonly则不默认static,如需要可以写static readonly;
- const是编译期静态解析的常量(因此其表达式必须在编译时就可以求值);readonly则是运行期动态解析的常量;
- const既可用来修饰类中的成员,也可修饰函数体内的局部变量;readonly只可以用于修饰类中的成员
前面是我从网上摘录的,文字太多,懒得自己再总结和打字了.
注意,第四点尤为重要,我用以下代码来说明和验证:
1.建立文本文件,然后改成.cs文件-lib.cs:
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConstReadonly_Base
- {
- public class Test
- {
- public const double PI = 3.14;
- public static readonly double pi = 3.14;
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConstReadonly_Base
{
public class Test
{
public const double PI = 3.14;
public static readonly double pi = 3.14;
}
}
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConstReadonly_Demo
- {
- class Program
- {
- static void Main(string[] args)
- {
- Console.WriteLine(ConstReadonly_Base.Test.PI);
- Console.WriteLine(ConstReadonly_Base.Test.pi);
- Console.ReadKey();
- }
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConstReadonly_Demo
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(ConstReadonly_Base.Test.PI);
Console.WriteLine(ConstReadonly_Base.Test.pi);
Console.ReadKey();
}
}
}
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- namespace ConstReadonly_Base
- {
- public class Test
- {
- public const double PI = 3.1415;
- public static readonly double pi = 3.1415;
- }
- }
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConstReadonly_Base
{
public class Test
{
public const double PI = 3.1415;
public static readonly double pi = 3.1415;
}
}

- .field public static literal float64 PI = float64(3.1415000000000002)
.field public static literal float64 PI = float64(3.1415000000000002)
- .field public static initonly float64 pi
.field public static initonly float64 pi
明显lib.cs被编译成元数据和IL汇编时,PI直接被替换成float64(3.1415000000000002)
而.cctor: void()静态构造函数中,
- .method private hidebysig specialname rtspecialname static
- void .cctor() cil managed
- {
- // Code size 15 (0xf)
- .maxstack 8
- IL_0000: ldc.r8 3.1415000000000002
- IL_0009: stsfld float64 ConstReadonly_Base.Test::pi
- IL_000e: ret
- } // end of method Test::.cctor
.method private hidebysig specialname rtspecialname static
void .cctor() cil managed
{
// Code size 15 (0xf)
.maxstack 8
IL_0000: ldc.r8 3.1415000000000002
IL_0009: stsfld float64 ConstReadonly_Base.Test::pi
IL_000e: ret
} // end of method Test::.cctor
pi是动态分配内存的,直到运行时才调用静态构造函数来初始化pi.
如果这时你还是不太明白,让我们接下去看:
用ILDasm工具,选择demo.exe,内容如下:

我们来看看Main函数中我们到底做了些什么:
- .method private hidebysig static void Main(string[] args) cil managed
- {
- .entrypoint
- // Code size 34 (0x22)
- .maxstack 8
- IL_0000: nop
- IL_0001: ldc.r8 3.1400000000000001
- IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
- IL_000f: nop
- IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
- IL_0015: call void [mscorlib]System.Console::WriteLine(float64)
- IL_001a: nop
- IL_001b: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
- IL_0020: pop
- IL_0021: ret
- } // end of method Program::Main
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 34 (0x22)
.maxstack 8
IL_0000: nop
IL_0001: ldc.r8 3.1400000000000001
IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
IL_000f: nop
IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
IL_0015: call void [mscorlib]System.Console::WriteLine(float64)
IL_001a: nop
IL_001b: call valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()
IL_0020: pop
IL_0021: ret
} // end of method Program::Main
WriteLine()打印PI时,
- IL_0001: ldc.r8 3.1400000000000001
- IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
IL_0001: ldc.r8 3.1400000000000001
IL_000a: call void [mscorlib]System.Console::WriteLine(float64)
这说明编译时,PI被编译成一个常量.
WriteLine()打印pi时,
- IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
IL_0010: ldsfld float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi
这说明编译时,pi被编译成调用ConstReadonly_Base.Test::pi,可见pi量是动态分配和调用的.
总结一下const和readonly的更多相关文章
- C#基础知识七之const和readonly关键字
前言 不知道大家对const和readonly关键字两者的区别了解多少,如果你也不是很清楚的话,那就一起来探讨吧!探讨之前我们先来了解静态常量和动态常量. 静态常量 所谓静态常量就是在编译期间会对变量 ...
- const 与 readonly知多少
原文地址: http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你cons ...
- [c#基础]关于const和readonly常见的笔试题剖析
引言 有那么几天没更新博客了,发现到了不得不写的地步,总是有那么个声音在强迫自己,虽然工作很累,但是有些东西不写出来,不能原谅自己.今天为什么总结这两个关键字的区别,总觉得这两个关键字的用法用的太习惯 ...
- const 和 readonly
const 和 readonly 的异同 Const readonly 字面意 不变常量,不可修改 只读操作,不可写 初始化 必须在声明的同时赋值 可在声明和构造方法中进行赋值 所属关系 类.即sta ...
- C#夯实基础系列之const与readonly
一.const与readonly的争议 你一定写过const,也一定用过readonly,但说起两者的区别,并说出何时用const,何时用readonly,你是否能清晰有条理地说出个一二三 ...
- 读书笔记:const和readonly、static readonly 那些事
C#中表示不变的量(常量)的两种形式:const 和readonly const 是静态常量 readonly 是动态常量 严格的来讲:const 应该称为常量 而readonly 则应称为只读变量. ...
- const和readonly区别
内容来源<<你必须知道的.NET>>(转载) 标题:什么才是不变:const和readonly 内容: const:用 const 修饰符声明的成员叫常量,是在编译期初始化并嵌 ...
- [转]const 与 readonly知多少
引自:http://www.cnblogs.com/royenhome/archive/2010/05/22/1741592.html 尽管你写了很多年的C#的代码,但是可能当别人问到你const与r ...
- const与readonly深度分析(.NET)
前言 很多.NET的初学者对const和readonly的使用很模糊,本文就const和readonly做一下深度分析,包括: 1. const数据类型的优势 2. const数据类型的劣势 3. r ...
- [c#] const 与 readonly
c# 中 const 与 readonly 关键字看似相同,实则不同.重点在于确定值的时间. const const 很简单,就是一个常量,不可以被 static 修饰,因为被 const 修饰的字段 ...
随机推荐
- Soap UI 数据库脚本(转)
3:在SoapUI的Test Case中新建Groovy Script连接数据库 接口如下 def sql = Sql.newInstance( 地址, 用户名, 密码, 驱动 ) 实现样例如下: i ...
- oracle 对象上锁,不能插入或删除情况
ora-00054:resource busy and acquire with nowait specified解决方法 当某个数据库用户在数据库中插入.更新.删除一个表的数据,或者增加一个表的主键 ...
- MVC 5 第三章 HTML Helper
提及到HTML helper大家肯定不应该陌生, 因为在书写MVC View的时候肯定需要使用到它.一个HTML Help就是一个返回HTML字符串的方法,这个字符串表示你所期望的类型的内容.例如,你 ...
- Weblogic 集群部署说明 --转
代理web.xml 设置 <servlet> l <servlet-name>HttpClusterServlet</servlet-nam ...
- JS获取浏览器可视区域尺寸
本文所说的是浏览器窗口的可视区域大小,不是浏览器窗口大小,也非页面尺寸. 在没有声明DOCTYPE的IE中,浏览器显示窗口大小只能以下获取: document.body.offsetWidth doc ...
- SQLite 入门教程(三)好多约束 Constraints(转)
转于: SQLite 入门教程(三)好多约束 Constraints 一.约束 Constraints 在上一篇随笔的结尾,我提到了约束, 但是在那里我把它翻译成了限定符,不太准确,这里先更正一下,应 ...
- java.lang.UnsupportedClassVersionError: Unsupported major.minor version 52.0的错误
1.首先检查是不是jdk版本过低,如果过低的话就把jdk重新安装一下 2.在编译器的版本中设置一下,compiler中设置成与jdk版本相同
- context-param和init-param区别
转载 http://www.cnblogs.com/hzj-/articles/1689836.html <context-param>的作用:web.xml的配置中<context ...
- 【转】使用VisualSVN Server搭建SVN服务器
http://blog.csdn.net/han_yankun2009/article/details/7856992 使用 VisualSVN Server来实现主要的 SVN功能则要比使用原始的 ...
- jQuery EasyUI, datagrid, treegrid formatter 参数比较 row index
如题: datagrid中,见官方文档: formatter function The cell formatter function, take three parameter:value: the ...