对C# 中Readonly的再认识
C#中有两种常量类型,分别为readonly(运行时常量)与const(编译时常量),本文将就这两种类型的不同特性进行比较并说明各自的适用场景。
工作原理
readonly为运行时常量,程序运行时进行赋值,赋值完成后便无法更改,因此也有人称其为只读变量。
const为编译时常量,程序编译时将对常量值进行解析,并将所有常量引用替换为相应值。
下面声明两个常量:
public static readonly int A = 2; //A为运行时常量
public const int B = 3; //B为编译时常量下面的表达式:
int C = A + B;经过编译后与下面的形式等价:
int C = A + 3;可以看到,其中的const常量B被替换成字面量3,而readonly常量A则保持引用方式。
声明及初始化
readonly常量只能声明为类字段,支持实例类型或静态类型,可以在声明的同时初始化或者在构造函数中进行初始化,初始化完成后便无法更改。
const常量除了可以声明为类字段之外,还可以声明为方法中的局部常量,默认为静态类型(无需用static修饰,否则将导致编译错误),但必须在声明的同时完成初始化。
数据类型支持
由于const常量在编译时将被替换为字面量,使得其取值类型受到了一定限制。const常量只能被赋予数字(整数、浮点数)、字符串以及枚举类型。下面的代码无法通过编译:
public const DateTime D = DateTime.MinValue;改成readonly就可以正常编译:
public readonly DateTime D = DateTime.MinValue;
可维护性
readonly以引用方式进行工作,某个常量更新后,所有引用该常量的地方均能得到更新后的值。
const的情况要稍稍复杂些,特别是跨程序集调用:
public class Class1
{
public static readonly int A = 2; //A为运行时常量
public const int B = 3; //B为编译时常量
}
public class Class2
{
public static int C = Class1.A + Class1.B; //变量C的值为A、B之和
}
Console.WriteLine(Class2.C); //输出"5"假设Class1与Class2位于两个不同的程序集,现在更改Class1中的常量值:
public class Class1
{
public static readonly int A = 4; //A为运行时常量
public const int B = 5; //B为编译时常量
}编译Class1并部署(注意:这时并没有重新编译Class2),再次查看变量C的值:
Console.WriteLine(Class2.C); //输出"7"结果可能有点出乎意料,让我们来仔细观察变量C的赋值表达式:
public static int C = Class1.A + Class1.B;编译后与下面的形式等价:
public static int C = Class1.A + 3;因此不管常量B的值如何变,对最终结果都不会产生影响。虽说重新编译Class2即可解决这个问题,但至少让我们看到了const可能带来的维护问题。
性能比较
const直接以字面量形式参与运算,性能要略高于readonly,但对于一般应用而言,这种性能上的差别可以说是微乎其微。
适用场景
在下面两种情况下:
a.取值永久不变(比如圆周率、一天包含的小时数、地球的半径等)
b.对程序性能要求非常苛刻
可以使用const常量,除此之外的其他情况都应该优先采用readonly常量。
对C# 中Readonly的再认识
很多人知道readonly 和 const 以及他们的区别和联系,本文只要对readonly 的一个小特性进行记录,属于读书笔记吧
请看如下代码
public sealed class AType
{
public static readonly Char[] TestChars = new Char[] {'A', 'B', 'C'};
}
这句代码很简单 我只是对静态只读字段TestChars赋初始值。这时候如果我问你我现在可以改变TestChars的值吗,你肯定会回答当然不可以,真的是这样吗,请仔细思考下.
请看如下代码

class Program
{
static void Main(string[] args)
{
AType.TestChars[0] = 'X';
AType.TestChars[1] = 'Y';
AType.TestChars[2] = 'Z';
Console.WriteLine(AType.TestChars[0]);
Console.Read();
}
}

这个输出结果是什么呢,是编译的时候报错还是会输出修改后的值“X”呢 答案是输出为“X”
在看如下代码

class Program
{
static void Main(string[] args)
{
AType.TestChars = new Char[] {'X', 'Y', 'Z'};
Console.WriteLine(AType.TestChars[0]);
Console.Read();
}
}

这个输出结果又是什么呢。。。 答案是编译出错提示“无法对静态只读字段赋值”
看到这里,我想大家都明白了:当某个字段是引用类型,并且该字段标记为readonly时,那么不可改变的是引用,而非字段引用的对象.
对C# 中Readonly的再认识的更多相关文章
- 关于C#中readonly
关于C#中readonly的一点小研究 关于C#中readonly的一点小研究 可能园子里有不少文章已经说明了这个问题了,但是我在这里写这篇博客只是写写自己的一些体会,也权当是整理归纳,高手莫见笑 ...
- winform中button点击后再点击其他控件致使button失去焦点,此时button出现黑色边线,去掉黑色边线的方法
winform中button点击后再点击其他控件致使button失去焦点,此时button出现黑色边线,去掉黑色边线的方法 button的FlatAppearence属性下,设置BorderSize= ...
- 关于C#中readonly的一点小研究
可能园子里有不少文章已经说明了这个问题了,但是我在这里写这篇博客只是写写自己的一些体会,也权当是整理归纳,高手莫见笑. ===============正文分割线================== 现 ...
- Spring 事务中 readOnly 的解释
spring 中事务的PROPAGATION_REQUIRED,Readonly的解释 (2012-11-21 16:29:38) 转载▼ 标签: 杂谈 一. ...
- 小鱼提问2 属性访问器中get,set再用public修饰行吗,private呢?
/// <summary> /// 是否有一个用户正在连接服务器中 /// </summary> public bool IsConnectting { get { retur ...
- python+opencv选出视频中一帧再利用鼠标回调实现图像上画矩形框
最近因为要实现模板匹配,需要在视频中选中一个目标,然后框出(即作为模板),对其利用模板匹配的方法进行检测.于是需要首先选出视频中的一帧,但是在利用摄像头读视频的过程中我唯一能想到的方法就是: 1.在视 ...
- Q他中的乱码再理解
Qt版本有用4的版本的也有用5的版本,并且还有windows与linux跨平台的需求. 经常出现个问题是windows的解决了,源代码放到linux上编译不通过或者中文会乱码,本文主要是得出一个解决方 ...
- IOS中录音后再播放声音太小问题解决
1.AVAudioSessionCategory说明 1.1 AVAudioSessionCategoryAmbient 或 kAudioSessionCategory_AmbientSound 用于 ...
- PL/SQL中复制中文再粘贴出现乱码问题的解决【转】
前不久!我对我的windowsxp做了一番大规模的设置:包括区域.系统.网络等方面的,结果当我设置完成以后,发现如果我从一些软件上复制内容到记事本里面会出现乱码,而且如果复制到word里面也不能够正常 ...
随机推荐
- C#函数式编程-序列
C#函数式编程之序列 过了许久的时间,终于趁闲暇的时间来继续将函数式编程这个专辑连载下去,这段时间开头是为IOS这个新方向做准备,将OC的教程写成了SWIFT版,当然我个人是支持Xamarin,但是我 ...
- Touch Punch在移动设备上面增加jQuery UI的触摸支持|Jquery UI 支持移动端 触摸滑动等
jQuery UI是我们前台开发常用的UI前端类库,但是目前的jQuery UI用户界面类库在互动和widget上并不支持touch事件.这意味着你在桌面上设计的优雅的UI可能在触摸设备,例如,ipa ...
- 图片alpha blending的计算
转载时请注明出处和作者联系方式:http://blog.csdn.net/mimepp作者联系方式:YU TAO <yut616 at sohu dot com> 一幅彩色图像的每一个像素 ...
- poj3744高速功率矩阵+可能性DP
Scout YYF I Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 4410 Accepted: 1151 Descr ...
- Java中间Map List Set和其他收藏品
Map List Set和其他收藏品: 一.概述 在JAVA的util包中有两个全部集合的父接口Collection和Map,它们的父子关系: +Collection 这个接口extends自 --j ...
- C++在struct与class差异
在C++中,既能够用structkeyword进行类的定义,也能够用classkeyword进行类的定义,那么这两者究竟有什么差别呢? 唯一的一点差别是:struct和class的默认訪问权限不一样. ...
- HDU 5185 Equation (DP)
题目:LINK 题意:求满足题目要求的x序列的种类数. 能够发现符合条件的序列去重后是一个0, 1, ..., k的连续序列(k满足k*(k+1)/2 <= n) ,则这个去重后的序列长度最长为 ...
- 大约ActionContext.getContext()使用体验
这是我在另一个人的博客看了,原来博客的时间长一点.我把它简化了一下,运营商,以方便它看起来. 为了避免与Servlet API耦合在一起,方便Action类做单元測试,Struts 2对HttpSer ...
- .9 png图片的制作
在android开发的过程中我们经常因为没有好的美工图片失真,这样使界面看起来要逊色很多,有的时候可能我们会想在drawable-hdpi,ldpi,mdpi下放不同分辨率的图片,这样虽然可以有效避免 ...
- QC邮件转发工具Mail Direct安装配置手册
QC邮件转发工具Mail Direct安装配置手册 2010-06-11 10:00:56| 分类: 软件测试 | 标签: |举报 |字号大中小 订阅 QC邮件转发工具安装配置手册 由于公司没有独立的 ...