您的位置:首页 > 其它

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

2012-06-15 16:57 453 查看
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要好一些。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: