zoukankan      html  css  js  c++  java
  • 总结一下const和readonly

    1. const和readonly的值一旦初始化则都不再可以改写;
    2. const只能在声明时初始化;readonly既可以在声明时初始化也可以在构造器中初始化;
    3. const隐含static,不可以再写static const;readonly则不默认static,如需要可以写static readonly;
    4. const是编译期静态解析的常量(因此其表达式必须在编译时就可以求值);readonly则是运行期动态解析的常量;
    5. const既可用来修饰类中的成员,也可修饰函数体内的局部变量;readonly只可以用于修饰类中的成员

    前面是我从网上摘录的,文字太多,懒得自己再总结和打字了.

    注意,第四点尤为重要,我用以下代码来说明和验证:

    1.建立文本文件,然后改成.cs文件-lib.cs:

     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace ConstReadonly_Base  
    7. {  
    8.     public class Test  
    9.     {  
    10.         public const double PI = 3.14;  
    11.         public static readonly double pi = 3.14;  
    12.     }  
    13. }  
     
    2.在命令行中输入: csc /t:library lib.cs,就会生成一个lib.dll文件.
    3.建立文本文件,然后改成.cs文件-demo.cs:
     
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace ConstReadonly_Demo  
    7. {  
    8.     class Program  
    9.     {  
    10.         static void Main(string[] args)  
    11.         {  
    12.             Console.WriteLine(ConstReadonly_Base.Test.PI);  
    13.             Console.WriteLine(ConstReadonly_Base.Test.pi);  
    14.             Console.ReadKey();  
    15.         }  
    16.     }  
    17. }  
    4.在命令行中输入: csc /r:lib.dll demo.cs,也就会生成一个demo.exe文件.
    双击,结果如下:
    3.14
    3.14
    5.更改lib.cs为:
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5.   
    6. namespace ConstReadonly_Base  
    7. {  
    8.     public class Test  
    9.     {  
    10.         public const double PI = 3.1415;  
    11.         public static readonly double pi = 3.1415;  
    12.     }  
    13. }  
      
    6.再次双击demo.exe文件,结果却如下:
    3.14
    3.1415
    (注: 直接双击demo.exe是直接运行,不再编译,上结果也就是运行期结束的结果,相当于跳过了编译)
     
    原因是什么呢?请听我慢慢道来.
    用ILDasm工具(这里假定你会用),选择lib.dll,内容如下:
    双击PI段:
    内容为
    1. .field public static literal float64 PI = float64(3.1415000000000002)  
    双击pi段:
    内容为
    1. .field public static initonly float64 pi  

    明显lib.cs被编译成元数据和IL汇编时,PI直接被替换成float64(3.1415000000000002)

    而.cctor: void()静态构造函数中,

    1. .method private hidebysig specialname rtspecialname static   
    2.         void  .cctor() cil managed  
    3. {  
    4.   // Code size       15 (0xf)  
    5.   .maxstack  8  
    6.   IL_0000:  ldc.r8     3.1415000000000002  
    7.   IL_0009:  stsfld     float64 ConstReadonly_Base.Test::pi  
    8.   IL_000e:  ret  
    9. // end of method Test::.cctor  

    pi是动态分配内存的,直到运行时才调用静态构造函数来初始化pi.

    如果这时你还是不太明白,让我们接下去看:

    用ILDasm工具,选择demo.exe,内容如下:

    我们来看看Main函数中我们到底做了些什么:

    1. .method private hidebysig static void  Main(string[] args) cil managed  
    2. {  
    3.   .entrypoint  
    4.   // Code size       34 (0x22)  
    5.   .maxstack  8  
    6.   IL_0000:  nop  
    7.   IL_0001:  ldc.r8     3.1400000000000001  
    8.   IL_000a:  call       void [mscorlib]System.Console::WriteLine(float64)  
    9.   IL_000f:  nop  
    10.   IL_0010:  ldsfld     float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi  
    11.   IL_0015:  call       void [mscorlib]System.Console::WriteLine(float64)  
    12.   IL_001a:  nop  
    13.   IL_001b:  call       valuetype [mscorlib]System.ConsoleKeyInfo [mscorlib]System.Console::ReadKey()  
    14.   IL_0020:  pop  
    15.   IL_0021:  ret  
    16. // end of method Program::Main  

    WriteLine()打印PI时, 

    1. IL_0001:  ldc.r8     3.1400000000000001  
    2. IL_000a:  call       void [mscorlib]System.Console::WriteLine(float64)  

    这说明编译时,PI被编译成一个常量.

    WriteLine()打印pi时,

    1. IL_0010:  ldsfld     float64 ['ConstReadonly-Base']ConstReadonly_Base.Test::pi  

    这说明编译时,pi被编译成调用ConstReadonly_Base.Test::pi,可见pi量是动态分配和调用的.

  • 相关阅读:
    关于java.lang.reflect.InvocationTargetException
    Java并发编程(三)后台线程(Daemon Thread)
    Lab 7-2
    Lab 7-1
    Lab 6-3
    Lab 6-2
    Lab 6-1
    Lab 5-1
    Lab 3-4
    Lab 3-3
  • 原文地址:https://www.cnblogs.com/kloseking/p/3163902.html
Copyright © 2011-2022 走看看