C# 定义常量 两种实现方法
在C#中定义常量的方式有两种,一种叫做静态常量(Compile-time constant),另一种叫做动态常量(Runtime constant)。前者用“const”来定义,后者用“readonly”来定义。 对于静态常量(Compile-time constant),它的书写方式如下:
public const int MAX_VALUE = 10;
为什么称它为静态常量呢,因为如上声明可以按照如下理解(注意:如下书写是错误的,会出编译错误,这里只是为了方便说明)。
public static
const int MAX_VALUE = 10;
用const定义的常量,对于所有类对象而言都是一样的,因此需要像访问静态成员那样去访问const定义的常量,而用对象的成员方式去访问会出变异错误。此外,对于静态常量的访问在编译的时候,是用常量的值去替换常量,例如:
int nValue = MAX_VALUE;
这句在编译之后,和如下这句所产生的中间语言代码是一样的。
int nValue =
10;
不过,在用const来定义常量的时候,在类型上有很多限制。首先,此类型必须属于值类型,同时此类型的初始化不能通过new来完成,因此一些用struct定义的值类型常量也不能用const来定义。
相对于const而言,用readonly来定义常量要灵活的多,它的书写方式如下:
public readonly int MAX_VALUE =
10;
为什么称为动态变量,因为系统要为readonly所定义的常量分配空间,即和类的其他成员一样拥有独立的空间。此外,readonly所定义的常量除了在定义的时候可以设定常量值外,还可以在类的构造函数中进行设定。由于readonly所定义的常量相当于类的成员,因此使用const来定义常量所受到的类型限制,在使用readonly去定义的时候全部消失,即可以用readonly去定义任何类型的常量。
综合上面所述,至于对比两者之间的区别具体如下。
静态常量(Compile-time constant) 动态常量(Runtime
constant)
定义 声明的同时要设置常量值。声明的时候可以不需要进行设置常量值,可以在类的构造函数中进行设置。
类型限制
首先类型必须属于值类型范围,且其值不能通过new来进行设置。 没有限制,可以用它定义任何类型的常量。
对于类对象而言
对于所有类的对象而言,常量的值是一样的。 对于类的不同对象而言,常量的值可以是不一样的。
内存消耗 无。 要分配内存,保存常量实体。
综述
性能要略高,无内存开销,但是限制颇多,不灵活。 灵活,方便,但是性能略低,且有内存开销。
对于在定义常量的时候,到底是用const来定义还是readonly来定义,我以前为了追求性能,因此尽量用const来定义。但是在此书中,提到了一个关于使用const会产生潜在的bug。就是在程序中使用DLL类库某个类的静态常量时,如果在类库中修改静态常量的值,其它接口没有发生变化,一般来说,程序调用端是不需要重新编译,直接执行就可以调用新的类库。不过就是在此情况下,会产生潜在的bug。这是由于静态常量在编译的时候,是用它的值去替换常量,因此在调用端的程序也是这样进行替换的。例如:在类库中定义了一个静态常量,如下:
public const int MAX_VALUE = 10;
那么对于程序中调用此静态常量这段代码,在编译后产生的中间语言代码中,是用10来进行替换,即使用静态常量的地方,改为10了。
那么当类库的静态变量发生变化后,例如:
public const int MAX_VALUE = 15;
那么对于调用端程序是可以在没有重新编译的情况下进行运行,不过此时程序的中间语言代码对应于静态变量的值是10,而不是新类库中的15。因此这样产生的不一致,程序会引发潜在的bug。解决此类问题的方法,就是调用端程序在更新类库之后重新编译一下,即生成新的中间语言代码。
对于如上在const定义常量时所存在的潜在bug,在用readonly定义常量时是不会发生的。因为readonly定义的常量类似于类的成员,因此在访问的时候需要根据具体常量地址来访问,从而避免此类bug。
鉴于此,本书建议用readonly来替换const去定义常量。
C# 定义常量 两种实现方法的更多相关文章
- 菜鸡的Java笔记 第十三 String 类的两种实例化方法
String 类的两种实例化方法 String 类的两种实例化方式的区别 String 类对象的比较 Stirng 类对象的使用分析 /* 1.String 类的两种实例化方式的区别 ...
- angular2系列教程(十)两种启动方法、两个路由服务、引用类型和单例模式的妙用
今天我们要讲的是ng2的路由系统. 例子
- 两种Ajax方法
两种Ajax方法 Ajax是一种用于快速创建动态网页的技术,他通过在后台与服务器进行少量的数据交换,可以实现网页的异步更新,不需要像传统网页那样重新加载页面也可以做到对网页的某部分作出更新,现在这项技 ...
- C#中的两种debug方法
这篇文章主要介绍了C#中的两种debug方法介绍,本文讲解了代码用 #if DEBUG 包裹.利用宏定义两种方法,需要的朋友可以参考下 第一种:需要把调试方法改成debug代码用 #if DEBU ...
- iOS学习——UITableViewCell两种重用方法的区别
今天在开发过程中用到了UITableView,在对cell进行设置的时候,我发现对UITableViewCell的重用设置的方法有如下两种,刚开始我也不太清楚这两种之间有什么区别.直到我在使用方法二进 ...
- 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结
史上最全的CSS hack方式一览 2013年09月28日 15:57:08 阅读数:175473 做前端多年,虽然不是经常需要hack,但是我们经常会遇到各浏览器表现不一致的情况.基于此,某些情况我 ...
- keil结合st-link使用SWO的两种调试方法笔记
通过strongerHuang的教程,实现了SWO的两种调试方法, 1.在keil调试的过程中,使用debug printf viewer打印信息, 2.在STM32 ST-LINK Utility中 ...
- bind()函数的深入理解及两种兼容方法分析
在JavaScript中,bind()函数仅在IE9+.Firefox4+.Chrome.Safari5.1+可得到原生支持.本文将深入探讨bind()函数并对两种兼容方法进行分析比较.由于本文将反复 ...
- git两种合并方法 比较merge和rebase
18:01 2015/11/18git两种合并方法 比较merge和rebase其实很简单,就是合并后每个commit提交的id记录的顺序而已注意:重要的是如果公司用了grrit,grrit不允许用m ...
随机推荐
- 3D动画
先上一道菜 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF ...
- ArcGIS发布地图服务
一般做完矢量图绘制工作后,生成的.mxd文件只能在ArcMap中查看,为了方便用户进行浏览,我们需要发布地图服务. 目前为止最常用的就是在ArcGIS中发布地图服务. 今天也算是在做“发布地图服务”的 ...
- Intellij IDEA中部署Tomcat报错“war exploded: Server is not connected. Deploy is not available”
最近将本机的Tomcat 7卸载重装了Tomcat 9后,在IDEA中运行Tomcat老是报错,一直未找到解决问题的办法. 只能讲Tomcat重新退回到版本7,才重新再IDEA中运行正常.
- Batman+joker乱谈
偶然一天内两次看到关于希斯·莱杰的文章(上面这个joker),貌似很多地方看到过这个,但是为什么他这么出名.知乎上的一篇文章 http://daily.zhihu.com/story/434137 ...
- (20)odoo中的action
---------更新时间18:06 2016-09-18 星期日15:05 2016-03-14 星期一18:07 2016-02-19 星期五---------* 窗口动作 <?xml ...
- Unique Paths [LeetCode]
A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The ...
- 集成 WeChat SDK - 支付篇
作者感言 惯例, 开头都是要说些东西的了, 随着现在的App越来越商业化, 很多公司的App都会集成第三方的支付SDK, 这样子的成本就比较低, 但是呢, 有很多朋友还是不太会集成, 也不太爱看集成文 ...
- iOS 中对 HTTPS 证书链的验证
这篇文章是我一边学习证书验证一边记录的内容,稍微整理了下,共扯了三部分内容: HTTPS 简要原理: 数字证书的内容.生成及验证: iOS 上对证书链的验证. HTTPS 概要 HTTPS 是运行在 ...
- 5月4日课堂内容:for循环的穷举、迭代
一.for循环拥有两类: 1.穷举: 把所有可能的情况都走一遍,使用if条件筛选出来满足条件的情况. 2.迭代: 从初始情况按照规律不断求解中间情况,最终推导出结果. 二.穷举练习 1.单位给发了一张 ...
- 【转】数据库范式(1NF 2NF 3NF BCNF)详解二
以下内容转自:http://jacki6.iteye.com/blog/774889 -------------------------分割线----------------------------- ...