C#中const和static有什么区别?

29

我渴望知道一个 const 变量和一个 static 变量之间的区别。

一个 const 变量是否总是 static?它们之间有什么区别?


11
常量变量并不存在。 - Hans Passant
5个回答

39

const字段只能保存值类型或System.String。它们必须是不可变的并且在编译时可解析。

static readonly字段通常可以保存引用类型(字符串以外),但这些类型只能在运行时创建。这些可以是可变类型,唯一不变的是引用本身。

如果您需要维护一组“常量”引用类型的实例,则通常使用一组public static readonly字段,例如System.Drawing.SystemColors的成员。

最后,readonly字段的初始化可以推迟到执行构造函数时进行,这意味着即使它只能被写入一次,它的初始化值不总是相同的。声明为const的真正常量只能有一个值(在编译时指定)。


2
一个静态只读字段可以在构造函数中更改,因此不同的构造函数可以为静态只读字段提供不同的值。 - Waleed Al-Balooshi

15

一种微妙但至关重要的区别是,consts 在编译时计算,而 statics 在运行时计算。这对版本控制有着重要的影响。例如,假设你写了以下代码:

public const int MaxValue = 100;
你编译并发布你的程序集(Assembly A)。然后其他人编写了一个引用 MaxValue 的程序集(Assembly B)。在这种情况下,值 100 编译进他们的程序集以及你的程序集。
如果你写了这个代码:
public static readonly int MaxValue = 100;

那么他们汇编中的引用只会保持那样,即一个引用。当某人运行汇编B时,值100将从你的汇编A中加载。

例如,这可能会影响简单的修补程序场景。如果发出已声明MaxValues为200的更新后的Assembly A,并且用户将该版本复制到以前的版本上(但不重新编译Assembly B),则在第一种情况下,Assembly B将继续像MaxValues为100一样运作,因为这是编译到Assembly B中的const值。在第二种情况下,Assembly B将在运行时加载非const静态变量并获取新值。


6
正如你所说,静态(static)和常量(const)都是附加在一个类型(type)上而不是一个类型的实例(instance)上。但是,您仍然可以更改静态(items)。您无法更改常量(items)。
但要小心。如果您的常量(item)是引用类型(reference type),分配的表达式必须在编译时进行评估,这意味着您可以给引用的唯一可能值是 null(具有重要且有用的例外字符串)。

这听起来不对。静态关键字同样适用于字段。而唯一可能的const引用类型是字符串。你无法更改一个字符串。 - Hans Passant
值得注意的是,const 只能保存字符串和 null 这两种引用类型。 - Waleed Al-Balooshi
在我写下这句话后,它听起来对我也不太对。所以我去检查了一下——你确实可以有一个引用类型的常量。我知道这是可能的。但除了字符串之外,当你这样做时必须为 null。我更新了我的答案以反映这一点。 - Joel Coehoorn
常量表达式是指可以在编译时完全计算的表达式。因此,引用类型的常量可能的唯一值是字符串和 null。参考链接:http://msdn.microsoft.com/en-us/library/e6w8fe1b(VS.85).aspx - Joel Coehoorn

3

一个非只读的静态变量在声明之后可以被修改,而常量则不能。此外,常量不能使用函数来设置,但是静态变量可以。


0

常量是一个在值上不能被改变的变量。

静态变量是一个不能在其声明范围之外使用的变量。也就是说,如果它是一个全局变量,则只能在声明它的文件中使用。如果它是一个函数内部的变量,则只能在该函数内部使用。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接