二维码 短网址 cnBeta

《Effective C#》读书笔记-1.C# 语言习惯-2.使用运行时常量(readonly)而不是编译时常量(const)

概念

  • 编译时


编译时顾名思义就是正在编译的时候。那啥叫编译呢?就是编译器帮你把源代码翻译成机器能识别的代码。(当然只是一般意义上这么说,实际上可能只是翻译成某个中间状态的语言。比如Java只有JVM识别的字节码,C#中只有CLR能识别的MSIL。另外还有链接器、汇编器。为了了便于理解我们可以统称为编译器)

那编译时就是简单的作一些翻译工作,比如检查你有没有粗心写错啥关键字了啊。有啥词法分析,语法分析之类的过程。就像个老师检查学生的作文中有没有错别字和病句一样。如果发现啥错误编译器就告诉你。如果你用微软的VS的话,点下build。那就开始编译,如果下面有errors或者warning信息,那都是编译器检查出来的。所谓这时的错误就叫编译时错误,这个过程中做的啥类型检查也就叫编译时类型检查,或静态类型检查(所谓静态就是没把代码放内存中运行起来,而只是把代码当作文本来扫描下)。

  • 运行时

所谓运行时就是代码跑起来了。被装载到内存中去了。(你的代码保存在磁盘上没装入内存之前是个死家伙。只有跑到内存中才变成活的)。而运行时类型检查就与前面讲的编译时类型检查(或者静态类型检查)不一样。不是简单的扫描代码。而是在内存中做些操作,做些判断。

代码  

为了更加直观的理解编译时和运行时的区别,我们看以下代码:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             mm a = new mm();
 6 
 7             nn b = new nn();//实例化一个nn的对象b
 8 
 9             mm c = b; //把mm的对象c指向b
10 
11             Console.WriteLine("非虚方法");
12 
13             a.F();
14             b.F();
15             c.F();
16 
17             Console.WriteLine("虚方法");
18             a.G();
19             b.G();
20             c.G();
21             Console.ReadKey();
22         }
23     }
24     class mm
25     {
26         public void F()
27         {
28             Console.WriteLine("mm.F()");
29         }
30 
31         public virtual void G()        //声明了一个虚方法
32         {
33             Console.WriteLine("mm.G()");
34         }
35     }
36     class nn : mm
37     {
38         new public void F()         //隐藏了父类的F方法
39         {
40             Console.WriteLine("nn.F()");
41         }
42 
43         public override void G()        //重写了方法G
44         {
45             Console.WriteLine("nn.G()");
46         }
47     }

运行结果截图如下:

对象a,b没有问题,但对象c的编译时类型为mm,那是因为对象a,b,c都是引用类型,运行时类型=编译时类型,但对于虚方法来说,调用哪个方法取决于该实例运行时的类型。

总结

 2.用运行时常量(readonly)而不是编译时常量(const)
    运行时常量(readonly)
        不能声明在方法中
        使用更灵活,便于后期维护
        运行时求值
        能使用任意类型
        二进制层次兼容
    编译时常量(const)
        可声明在方法中
        性能优于readonly
        值在目标代码中替换
        仅能用于基本类型(内建的整数和浮点类型)、枚举或字符串
        二进制层次不兼容
        在编译时必须得到确定数值(或永远都不会改变)时使用,例如attribute的参数和枚举的定义等

posted @ 2017-04-27 11:29  何苦而乐  阅读(192)  评论(0编辑  收藏  举报
返回顶部