《Effective C#》读书笔记——条目2:用运行时常量而不是编译期常量<C#语言习惯>

简介:

  C#语言中有两种类型的常量:编译期常量运行时常量。应该尽量使用运行时常量,而不是编译期常量。虽然编译期常量略快一些,但是没有运行时常量那么灵活。应仅仅在那些性能异常敏感,且常量的值在各个版本之间绝对不会变化时,才使用编译器常量。

  运行时常量使用readonly关键字声明,编译时常量使用const关键字声明:

1         //编译时常量,可以声明在方法中
2         public const int Millennium = 2000;
3         //运行时常量,不能声明在方法中
4         public static readonly int ThisYear = 2012;

 

运行时常量(readonly)和编译时常量(const)的不同

  二者的不同之处在于对它们的访问方式不同。编译时常量的值是在在目标代码中进行替换的,以下两个构造生产的IL代码时一样的:

if(myDateTime.Year == Millennium)
if(myDateTime.Year == 2000)

这也就导致了编译期常量仅能用于基本类型(内建的整数和浮点类型)、枚举或字符串。在编译后得到的IL代码中,只有这些常量可以直接被替换成为它们的字面值。

运行时常量将在运行时求值,在构造函数执行后不能被再次修改。引用运行时常量生成的IL将引用到readonly的变量,而不是变量本身的值(灵活)。

二者的区别在于:readonly的值将在运行时给出,这会带来更好的灵活性。例如,运行时常量可以为任意类型。readonly字段必须在构造函数或初始化器中初始化,而 const 字段只能在该字段的声明中初始化。

 

我们可以做一个假设:在一个名为Customer的程序集中分别定义了一个const字段和readonly字段:

1  class Customer
2     {
3         public static readonly int StartValue = 5;
4         public const int EndValue = 10;
5

 

另一个程序集中引用了这两个值,当我们过了一段时间需要更新Customer程序集的这两个字段将值更改:

1     class Customer
2     {
3         public static readonly int StartValue = 15;
4         public const int EndValue = 20;
5     }

 

随后,分发Customer程序集,而没有重新编译整个应用程序时,我们可以发现在并没有重写编译整个应用程序的情况下所以引用了readonly字段的值变成了我们更新的值,而其他引用了const字段的值却没有更新。

这是因为:

编译器第一次编译应用程序的时候:将所有引用了const字段的变量的值替换成了它对应的常量值(5);对应所有引用readonly字段的变量来说引用的是这个声明为readonly的字段,而不是其字面值。

所以说若想修改所有使用readonly的客户代码的行为,只需要简单的更新一下这个声明了readonly字段的程序集就可以了。而想要更新所有使用const的客户代码的行为则需要重新编译整个应用程序。

 

小结:

  只有在编译期必须获得确定数值时一定要使用const。例如特性(attribute)的参数和枚举的定义等,还有那些在各个版本发布之间不会变化的值。在除此之外的所以情况下,都应该经理选择更加灵活的readonly常量。

 

阅读书目:《Effective C#》

本文转自gyzhao博客园博客,原文链接:http://www.cnblogs.com/IPrograming/archive/2012/08/21/Effective_CSharp_02.html ,如需转载请自行联系原作者
相关文章
|
7月前
|
存储 安全 数据库连接
C#深度揭秘:常量的魅力和实践,一文让你从新手到专家
C#深度揭秘:常量的魅力和实践,一文让你从新手到专家
56 0
|
7月前
|
C# 开发者
C# 10.0引入常量插值字符串:编译时确定性的新篇章
【1月更文挑战第22天】在C# 10.0中,微软为开发者带来了一项引人注目的新特性——常量插值字符串。这一功能允许在编译时处理和计算字符串插值表达式,从而得到可以在编译时确定的常量字符串。本文将深入探讨C# 10.0中常量插值字符串的概念、工作原理、使用场景及其对现有字符串处理方式的改进,旨在帮助读者更好地理解和应用这一强大的新特性。
|
2月前
|
缓存 C# Windows
C#程序如何编译成Native代码
【10月更文挑战第15天】在C#中,可以通过.NET Native和第三方工具(如Ngen.exe)将程序编译成Native代码,以提升性能和启动速度。.NET Native适用于UWP应用,而Ngen.exe则通过预编译托管程序集为本地机器代码来加速启动。不过,这些方法也可能增加编译时间和部署复杂度。
152 2
|
4月前
|
编译器 C# Windows
C#基础:手动编译一个.cs源代码文件并生成.exe可执行文件
通过上述步骤,应该能够高效准确地编译C#源代码并生成相应的可执行文件。此外,这一过程强调了对命令行编译器的理解,这在调试和自动化编译流程中是非常重要的。
349 2
|
C# Windows
[记录]c#.net framework 4.5调用运行时库
[记录]c#.net framework 4.5调用运行时库
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
选中项目,点击右上角的显示全部文件按钮,会将默认隐藏的文件显示出来,选中所需图片,右键,添加到项目,然后选择图片查看属性,生成操作选择resource。完毕。本人目前的解决方案。
482 41
C#WPF 图片在显示时没有问题,但在运行时图片显示不出来的解决
|
6月前
|
开发框架 .NET 编译器
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
程序与技术分享:C#基础知识梳理系列三:C#类成员:常量、字段、属性
40 2
|
6月前
|
存储 C# 开发者
C# 编程基础:注释、变量、常量、数据类型和自定义类型
C# 编程基础:注释、变量、常量、数据类型和自定义类型
《More Effective C# 》读书笔记 第一章
《More Effective C# 》读书笔记 第一章
|
存储 安全 编译器
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(下)
[笔记]读书笔记 C++设计新思维《一》基于策略的类设计(下)