• const和readonly


    在很多时候,或者很多朋友都认为const和readonly其实是一样的,它们都表示了一个不可变的值,也就是我们所谓的常量吧.它们的区别在于

    • const是编译时常量
    • readonly是运行时常量

    那么,什么是编译时常量?也就是在编译时就决定了的常量,这样的好处是效率高。因为它直接就用常量值编译在所有引用的代码里面。如下面所示

    //Compile time constant:
    public cocnst int _Millennium = 2000;

    一个编译时常量会被目标代码中的值直接取代。下面的代码:
    if(myDateTime.Year == _Millennium)
    会与下面写的代码编译成完全相同的IL代码:
    if(myDateTime.Year == 2000)

    如果这样,当然效率会比较高。但是,这样做会有下面一个问题

    假设有一个主程序,它会引用另外一个程序集,而该程序集中使用了const常量。我们来看看

    1. 程序集(代码很简单)

    using System;
    using System.Collections.Generic;
    using System.Text;

    namespace ClassLibrary1
    {
        public class Class1
        {
            public const string VERSION = "VERSION 1.0";
        }
    }

    2. 主程序

    class Program
    {
        static void Main(string[] args)
        {
           Console.WriteLine(ClassLibrary1.Class1.VERSION);
            Console.Read();
        }
    }

    3.调试程序,当然是可以很正确地显示出来版本号

    image

    4. 假设我们此时,对ClassLibrary1进行了更新,修改了常量值

    public class Class1
    {
         public const string VERSION = "VERSION 2.0";
    }

    5. 此时,我们重新编译ClassLibrary。

    【注意】我们不编译主程序。直接把ClassLibrary的编译结果复制过去。

    6. 此时运行主程序,你会发现主程序仍然是显示出来VERSION 1.0

    image

    你很诧异对吧?但这就是编译时常量的结果。我们可以来看看主程序里面的MSIL代码

    image

    你可以看到,其实在MSIL里面已经将VERSION 1.0进行了硬编码,也就是说,除非你重新编译主程序,它才会更改这个常量的值。

    反过来说,如果在ClassLibrary中使用readonly变量,则在MSIL中保存的是一个变量的引用,那么这就叫运行时常量,它会动态读取程序集中的常量值。

    public static readonly string Author = "Chenxizhang";//定义运行时常量

    image

    通过上面的讲解,我们可以得出一个结论

    1. 如果一个常量永远不会变化,那么可以使用const定义常量,这样可以获得更加好的性能。(虽然性能其实相差不大)

    2. 反之,则应该优先考虑用readonly

  • 相关阅读:
    动态横向(水平)合并Repeater数据行DataItem的列
    动态绑数据(Repeater控件HeaderTemplate和ItemTemplate)
    动态横向(水平)合并GridView数据行DataRow的列
    动态绑数据(GridView控件Header和ItemTemplate)
    用具体列名替代星号
    如何实现数据行转换列显示
    用LINQ获取XML节点数据
    从字符串中获取XML节点数据
    字符串创建XML文档
    根据Attribute值条件对XML文档进行修改
  • 原文地址:https://www.cnblogs.com/chenxizhang/p/1439400.html
Copyright © 2020-2023  润新知