Effective C# 条款2

2011040514494412.jpg

 图1编译时常量和运行时常量区别

 

  编译时常量比运行时常量稍微快一点,但却缺乏灵活性,但如果程序“慢”能确保正确运行,“快”有可能导致出错,那么我相信大家考虑到“常量之间何必在乎那一点点误差呢”当然稳定性首选的是运行时常量。

 
  
// 编译时常量声明:

public const int _Millennium = 2000 ;



// 运行时常量声明:

public static readonly int _ThisYear = 2011 ;

 2011040514541250.jpg

2011040514543415.jpg

                         图2 运行时和编译时常量的MSIL代码

  通过比较编译时常量和运行时常量的MSIL代码发现,编译常量在编译后为变量提供常量值,而运行时常量并没有提供常量值。

  我们知道,运行时常量和编译时常量最重要的区别就在于运行时常量值的辨析发生在运行时,而编译时常量值的辨析发生编译时。换言之,使用运行时常量编译后的 IL 代码引用的是 readonly 变量,而非它的值;而使用编译时常量编译后的 IL 代码将直接引用它的值——就像我们直接在代码中使用常量值一样。即使我们使用的是数值常量并跨程序集引用,情况也是一样:如果在程序集 A 中引用程序集 B 中的常量,那么编译后程序集 A 中出现的那个常量将被它的值所替换。这种差别对于代码的维护性而言有着相当的影响。

现在让我们看一下它们的区别:

 
  
/// <summary>
/// 定义运行时常量和编译时常量
/// </summary>
public class TestClass
{
public const int isConstVar = 5 ;
public static readonly int inReadonlyVar = 1 ;
}
 
  
/// <summary>
/// 测试运行时和编译时常量区别
/// </summary>
class Program
{
static void Main( string [] args)
{
for ( int i = TestClass.TestClass.inReadonlyVar; i < TestClass.TestClass.isConstVar; i ++ )
{
Console.WriteLine(
" This is {0} " , i);
}
Console.ReadKey();
}
}

2011040514564669.jpg

      图3输出结果

2011040514572010.jpg

图4编译常量和运行常量MSIL

 

 

  通过上面我们可以发现编译时常量是通过hard code方式替换为一个值常量,而运行时常量是通过一个引用方式来,如果我们修改编译时常量值为10,而运行时常量值为3,修改如下:

 
  
public class TestClass
{
public const int isConstVar = 10 ;
public static readonly int inReadonlyVar = 3 ;
}

  

  如果我们重新编译TestClass,然而不重新编译Program控制台应用程序,而且把重新编译后的TestClass copy到控制台应用程序的bin中再次运行,大家可以猜猜看最后输出的结果,我相信聪明的你肯定可以猜得到结果,没错结果如下:

2011040514581415.jpg

2011040514582754.jpg

2011040514584071.jpg

    图5输出结果

 

 

  分析原因在于C#编译器在第一次编译控制台应用程序集时,将其中的 isConstVar替换成了它对应的常量值5,而对于 inReadonlyVar来说,由于它被声明为 readonly,所以它的辨析发生在运行时。因此,控制台应用程序集在没有被重新编译的情况下, 仍然可以使用新的 inReadonlyVar值。

转载于:https://www.cnblogs.com/rush/archive/2011/04/05/Effective_CSharp.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值