const和readonly你真的懂吗?
第二遍文章我打算把const和readonly的区别拿出来讲下,因为写代码这么久我都还没搞清楚这两者的区别,实在有点惭愧,所以这一次我打算搞清楚它。
定义
来看看MSDN的解释:
readonly:readonly关键字是可以在字段上使用的修饰符。当字段声明包括readonly修饰符时,该声明引入的字段赋值只能作为声明的一部分,或者出现在同一类的构造函数中。
const:使用 const 关键字来声明某个常量字段或常量局部变量。 常量字段和常量局部变量不是变量并且不能修改。
太多理论的讲解有些人可能看了更犯晕,所以直接写些代码我觉得可能比较直观好理解。
举例
我们先来看下const
- public class ConstTest
- {
- class SampleClass
- {
- public int x;
- public int y;
- public const int c1 = ;
- public const int c2 = c1 + ;
- public static const int z=8; //这个写法错误,因为const是静态常量,可看下面提供c1的IL语言图片。
- //变量可以在这里初始化值,但是如果把const放在这里初始化,编译会出错(赋值号左边必须为变量、属性或索引器)
- public SampleClass(int p1, int p2)
- {
- x = p1;
- y = p2;
- }
- }
- static void Main()
- {
- SampleClass mC = new SampleClass(, );
- Console.WriteLine("x = {0}, y = {1}", mC.x, mC.y);
- Console.WriteLine("c1 = {0}, c2 = {1}",SampleClass.c1, SampleClass.c2); //类型引用
- }
- }
- /* Output
- x = 11, y = 22
- c1 = 5, c2 = 10
- */
- 来看下IL语言:
c2和y省略在这里省略,从上面的图我们得出了一个结论:
那就是静态常量,那什么是静态常量呢?静态常量是指编译器在编译时候会对常量进行解析,并将常量的值替换成初始化的那个值。即图中里面的c1和c2,它们都是在编译的时候值就确定下来(c1=5,c2=10),这个相信大家也比较好理解。
我们再来看readonly:
- public class ReadOnlyTest
- {
- class SampleClass
- {
- public readonly int x;
- public readonly int y = ;
- public static readonly int z=;
- //无参构造函数初始化readonly常量
- public SampleClass()
- {
- y = ;
- }
- //静态无参构造函数内初始化static readonly常量
- static SampleClass()
- {
- z = ;
- }
- //有参构造函数初始化readonly常量
- public SampleClass(int p1, int p2)
- {
- x = p1;
- y = p2;
- }
- }
- static void Main()
- {
- //访问静态成员
- Console.WriteLine(SampleClass.z);
- //访问非静态成员
- SampleClass p1 = new SampleClass(, ); // OK
- Console.WriteLine("p1: x={0}, y={1}", p1.x, p1.y);
- SampleClass p2 = new SampleClass();
- Console.WriteLine("p2: x={0}, y={1}", p2.x, p2.y);
- Console.ReadKey();
- }
- }
- /*
- Output:
- 23
- p1: x=11, y=21
- p2: x=0, y=24
- */
- 同样的,来看IL语言:
我们先看下什么是动态常量:
动态常量,是指值在运行的那一刻才获得的,编译器编译期间将其标示为只读常量,而不用常量的值代替,这样动态常量不必在声明的时候就初始化,而可以延迟到构造函数中初始化。
通过const和readonly的代码我们可以得出以下结论:
1.readonly和static readonly定义的常量,指定初始值后(包括在构造函数内指定初始值)将不可更改,可读不可写。
2.static readonly常量,如果在构造函数内指定初始值,则必须是静态无参构造函数,例如z参数的初始化过程。
3.const和static readonly定义的常量是静态的,只能由类型直接访问;而readonly定义的常量是非静态的,只能由实例对象访问。
const和readonly比较
1.const默认是静态的,只能由类型访问,不能和static同时使用,否则编译错误;readonly默认是非静态,由实例对象来访问,可以显式使用static定义为静态成员。
2.const只能引用在值类型和string类型上,其他引用类型常量必须声明为null,否则以new为const引用类型常量赋值,编译器会提示错误,原因是构造函数初始化在运行时,而非编译时;readonly只读字段可以是任意类型,但是对于引用类型字段来说,readonly不能限制对该对象实例成员的读写控制。
3.const必须在字段声明时初始化;而readonly可以在声明时,或者构造函数中进行初始化,不同的构造函数可以为readonly常量实现不同的初始值
4.const可以定义字段和局部变量;而readonly则只能定义字段
5.const由于是静态常量所以在编译时会对常量进行解析,而readonly是动态常量在编译期间编译器将其标示为只读常量,而不用常量的值代替,这样就不必在声明的时候就初始化,而可以延迟到构造函数中初始化
6.从应用角度来看,对于恒定不变且单独使用的量来说,应该考虑声明为const常量,例如性能比,百分比等;而对于可能随实际运行发生变化的量,应该考虑声明readonly常量,例如日期或时间,数据库中的主键id等
以上内容希望对一些朋友带来帮助~~~
const和readonly你真的懂吗?的更多相关文章
- 程序猿修仙之路--数据结构之你是否真的懂数组? c#socket TCP同步网络通信 用lambda表达式树替代反射 ASP.NET MVC如何做一个简单的非法登录拦截
程序猿修仙之路--数据结构之你是否真的懂数组? 数据结构 但凡IT江湖侠士,算法与数据结构为必修之课.早有前辈已经明确指出:程序=算法+数据结构 .要想在之后的江湖历练中通关,数据结构必不可少. ...
- 你真的懂printf么?
自从你进入程序员的世界,就开始照着书本编写着各种helloworld,大笔一挥: printf("Hello World!\n"); 于是控制台神奇地出现了一行字符串,计算机一句温 ...
- [C#] C# 知识回顾 - 你真的懂异常(Exception)吗?
你真的懂异常(Exception)吗? 目录 异常介绍 异常的特点 怎样使用异常 处理异常的 try-catch-finally 捕获异常的 Catch 块 释放资源的 Finally 块 一.异常介 ...
- 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 则应称为只读变量. ...
随机推荐
- c++ string.find()函数的陷阱
string.find(char *)查找字符串中是否包含子串 找到:返回第一个索引 没有找到:返回一个很大的随机数字而不是返回负数(这是个坑) 所以不能这么写if (string.find(str) ...
- How to change a product dropdown attribute to a multiselect in Magento
First, update the attribute input type to multiselect: UPDATE eav_attribute SET entity_type_id ', at ...
- Gunner II(二分,map,数字转化)
Gunner II Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others) Total ...
- WdatePicker日历控件用法
1. 跨无限级框架显示 不管你把日期控件放在哪里,你都不须要操心会被外层的iframe所遮挡进而影响客户体验,由于My97日期控件是能够跨无限级框架显示的 演示样例2-7 跨无限级框架演示 可无限跨越 ...
- ChartControl一个小Demo
我X轴设置的是时间,类型是DatetimeY轴设置的是数量,类型是Numerical当日期不一样时显示曲线正常,但是如果是同一天的话就成了下面的效果 怎么做才能让全部是同一天的时候显示小时为单位的曲线 ...
- mvc+ef5+easyui实例(1)
mvc+ef5+easyui 组织机构和员工管理实例 环境:vs2010+sql2008 框架搭建 1,新建mvc4 web应用 2. 3. 系统自动生成的的controllers,和views文件中 ...
- 学习Javascript DOM 编程艺术的一点心得
最近又看了一遍JS DOM编程艺术,照例来写一写读后感. 其实,我从中学到最深的是几个概念:1.平稳退化.当浏览器并不支持JS的时候网页的基本核心功能是还可以用的:2.逐渐增强.在原始的信息层上用其他 ...
- poj1160
题目大意:在一个一维坐标轴上有v个(1<=v<=300)村庄,要建p(1<=p<=30)个邮局,每个村庄都到最近的邮局,要求最小的距离和. 四边形不等式,据说黑书上写得很高 ...
- PHP中计算时间差(上周,上月,去年,昨天等)
运用了date()和strtotime()函数,直接上代码 echo date('Y-m-d' , strtotime('-1 day')).PHP_EOL; echo date('Y-m-d' , ...
- 【Chromium中文文档】进程模型
进程模型 转载请注明出处:https://ahangchen.gitbooks.io/chromium_doc_zh/content/zh//General_Architecture/Process_ ...