zoukankan      html  css  js  c++  java
  • 《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#》

  • 相关阅读:
    MySql 用户 及权限操作
    MAC 重置MySQL root 密码
    在mac系统安装Apache Tomcat的详细步骤[转]
    Maven:mirror和repository 区别
    ES6 入门系列
    转场动画CALayer (Transition)
    OC 异常处理
    Foundation 框架
    Enum枚举
    Invalid App Store Icon. The App Store Icon in the asset catalog in 'xxx.app' can’t be transparent nor contain an alpha channel.
  • 原文地址:https://www.cnblogs.com/IPrograming/p/Effective_CSharp_02.html
Copyright © 2011-2022 走看看