常量
const
用于表示在程序的整个生命周期中永远不会改变的值。它的值在编译时是常量,而不是 readonly
关键字,其值在运行时是常量。
例如,由于光速永远不会改变,我们可以将它存储在一个常数中。
const double c = 299792458; // Speed of light
double CalculateEnergy(double mass)
{
return mass * c * c;
}
这与 return mass * 299792458 * 299792458
基本相同,因为编译器将直接用其常量值替换 c
。
因此,c
一旦声明就无法更改。以下将产生编译时错误:
const double c = 299792458; // Speed of light
c = 500; //compile-time error
常量可以使用与方法相同的访问修饰符作为前缀:
private const double c = 299792458;
public const double c = 299792458;
internal const double c = 299792458;
const
成员本质上是 static
。但是,不允许明确使用 static
。
你还可以定义方法本地常量:
double CalculateEnergy(double mass)
{
const c = 299792458;
return mass * c * c;
}
这些不能以 private
或 public
关键字作为前缀,因为它们隐含在它们定义的方法的本地。
并非所有类型都可以在 const
声明中使用。允许的值类型是预定义类型 sbyte
,byte
,short
,ushort
,int
,uint
,long
,ulong
,char
,float
,double
,decimal
,bool
和所有 enum
类型。尝试使用其他值类型(例如 TimeSpan
或 Guid
)声明 const
成员将在编译时失败。
对于特殊的预定义引用类型 string
,可以使用任何值声明常量。对于所有其他引用类型,可以声明常量,但必须始终具有值 null
。
因为 const
值在编译时是已知的,所以它们被允许作为 switch
语句中的 case
标签,作为可选参数的标准参数,作为属性规范的参数,等等。
如果在不同的程序集中使用 const
值,则必须注意版本控制。例如,如果程序集 A 定义了 public const int MaxRetries = 3;
,而程序集 B 使用该常量,那么如果 MaxRetries
的值稍后在程序集 A 中更改为 5
(然后重新编译),则该更改在程序集 B 中将无效,除非程序集 B 也被重新编译(参考新版本的 A)。
因此,如果某个值可能会在程序的未来版本中发生更改,并且该值需要公开显示,请不要声明该值 const
,除非你知道每当更改某些内容时都会重新编译所有依赖程序集。替代方案是使用 static readonly
而不是 const
,它在运行时解析。