规则二 对常量使用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要好一些。
编译常量比运行常量会稍快,但是没有运行常量灵活。在性能要求非常严格但是数值不会改变的情况下使用编译常量。
编译常量
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要好一些。
相关文章推荐
- 创建常量时尽可能使用readonly,而不是const
- Effective C# 原则2:为你的常量选择readonly而不是const(译)
- 为你的常量选择readonly而不是const(译,转)
- Effective C# 原则2:为你的常量选择readonly而不是const(译)
- 2.为你的常量选择readonly而不是const
- Effective C# 原则2:为你的常量选择readonly而不是const
- EffectiveC#2--为你的常量选择readonly而不是const
- 原则2:为你的常量选择readonly而不是const
- 原则2:为你的常量选择readonly而不是const
- 【C#高效编程50例】条目2:用运行时常量(readonly)而不是编译期常量(const)
- Effiective C#:ITEM2:优先使用readonly而不是const
- Effective C# 原则2:为你的常量选择readonly而不是const
- 为你的常量选择readonly而不是const
- 使用const而不是宏来定义常量的好处
- Effective C# 原则2:为你的常量选择readonly而不是const[转载]
- [转]Effective C#原则2:为你的常量选择readonly而不是const
- 为你的常量选择readonly而不是const
- 详细解释下 const 常量 和 readonly 常量 的区别吧。
- Effective C# Item2:运行时常量(readonly)优于编译时常量(const)
- 【C#基础语言学习】:const,readonly 常量与只读的区别