规则二 对常量使用ReadOnly而不是const

1. C# 有两种类型的常量,编译类型常量和运行时常量。

编译常量比运行常量会稍快,但是没有运行常量灵活。在性能要求非常严格但是数值不会改变的情况下使用编译常量。

编译常量

public const int Millennium = 2000;

运行常量

public static readonly int ThisYear = 2004;

编译常量可以在方法体内定义,但是运行常量不行。

编译常量在编译成目标代码时,使用常量值取代常量名称。而运行常量并非如此。这个特点决定了编译常量只能使用原始类型的数据类型,而不能是对象。但是Readonly不受此限制。

另外,由于编译在编译成目标代码时把数字直接取代变量名称,即使跨越几个Assembly也同样如此,因此,在发行新的版本时,必须要全部重新编译,不然就会引起错误。

如在一个Assembly中定义

public class UsefulValues
{
    public static readonly int StartValue = 5;
    public const int EndValue = 10;
}


在另一个Assembly中使用

for (int i = UsefulValues.StartValue;
i < UsefulValues.EndValue; i++)
Console.WriteLine("value is {0}", i);


第一次运行打印结果如下:

Value is 5
Value is 6
...
Value is 9


过了若干时间,你修改程序

public class UsefulValues
{
public static readonly int StartValue = 105;
public const int EndValue = 120;
}


你期望得到如下结果

Value is 105
Value is 106
...
Value is 119


但是事实上你不会得到任何结果。因为StartValue 现在是105,而EndValue 依然是10.因为编译器会在整个应用的Assembly中把EndValue使用10来替换,因此,除非重新编译整个应用,不然EndValue 的值不会改变。


如果在一些情况中,值的确需要在编译时确定下来,比如序列化对象的版本。而只有当前版本号每次发布都不相同,需要在运行时确定。

private const int Version1_0 = 0x0100;
private const int Version1_1 = 0x0101;
private const int Version1_2 = 0x0102;
// major release:
private const int Version2_0 = 0x0200;
// check for the current version:
private static readonly int CurrentVersion =
Version2_0;


在每次保存的文件中写入当前版本号

// Read from persistent storage, check
// stored version against compile-time constant:
protected MyType(SerializationInfo info,
StreamingContext cntxt)
{
int storedVersion = info.GetInt32("VERSION");
switch (storedVersion)
{
case Version2_0:
readVersion2(info, cntxt);
break;
case Version1_1:
readVersion1Dot1(info, cntxt);
break;
// etc.
}
}


// Write the current version:
[SecurityPermissionAttribute(SecurityAction.Demand,
SerializationFormatter = true)]
void ISerializable.GetObjectData(SerializationInfo inf,
StreamingContext cxt)
{
// use runtime constant for current version:
inf.AddValue("VERSION", CurrentVersion);
// write remaining elements...
}

最好编译常量的优势就是效率比Readonly要好一些。




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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值