常量

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;
}

这些不能以 privatepublic 关键字作为前缀,因为它们隐含在它们定义的方法的本地。

并非所有类型都可以在 const 声明中使用。允许的值类型是预定义类型 sbytebyteshortushortintuintlongulongcharfloatdoubledecimalbool 和所有 enum 类型。尝试使用其他值类型(例如 TimeSpanGuid)声明 const 成员将在编译时失败。

对于特殊的预定义引用类型 string,可以使用任何值声明常量。对于所有其他引用类型,可以声明常量,但必须始终具有值 null

因为 const 值在编译时是已知的,所以它们被允许作为 switch 语句中的 case 标签,作为可选参数的标准参数,作为属性规范的参数,等等。

如果在不同的程序集中使用 const 值,则必须注意版本控制。例如,如果程序集 A 定义了 public const int MaxRetries = 3;,而程序集 B 使用该常量,那么如果 MaxRetries 的值稍后在程序集 A 中更改为 5(然后重新编译),则该更改在程序集 B 中将无效,除非程序集 B 也被重新编译(参考新版本的 A)。

因此,如果某个值可能会在程序的未来版本中发生更改,并且该值需要公开显示,请不要声明该值 const,除非你知道每当更改某些内容时都会重新编译所有依赖程序集。替代方案是使用 static readonly 而不是 const,它在运行时解析。