15

为什么以下工作?

class A
{
    public int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };

    static void Main(string[] args)
    {
    }
}

而以下没有?

class A
{
    public const int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };

    static void Main(string[] args)
    {
    }
}

它不允许将字符串以外的 const 引用类型分配为 null 以外的任何内容。由于它是一个数组(引用),因此必须为其分配 null(?)。如果它是常量且为空,它将如何初始化?

4

3 回答 3

18

如果我没记错的话,它是 C# 语言设计的一部分。const保留用于可以在编译时推断其内容的项目,即在程序甚至构建然后运行之前(期间)。C# 中的所有数组都是运行时数组(它们的长度是在程序运行时确定的,而不是在那之前),因此它们不能被制成const字段。我觉得这是 C# 的一个限制,但这就是他们决定这样做的方式。

引用类型可以为 null 的原因是它null是一个常量值,而您的初始化程序(在运行时生成)不是。null内置于语言中,因此通过该逻辑,它的值始终是已知的(因此,可用于编译时引用类型)。

编辑:

但是,您应该能够创建一个静态表,该表将在任何其他代码使用或需要它时被初始化:

public static int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
       ^ Static Keyword

您可以像访问它(如果它仍在class A):

A.i[0, 1]

我希望这可以帮助你

要了解更多信息,请查看 MSDN: http: //msdn.microsoft.com/query/dev11.query?appId=Dev11IDEF1&l=EN-US&k=k(CS0134);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5) &rd=真

编辑编辑:如果您需要将静态表铆接到代码上,并且在初始化后永远不要让任何人更改它,则有用于此readonly目的的关键字:

public static readonly int[,] i = { { 1, 2, 3 }, { 1, 2, 3 }, { 1, 2, 3 } };
       ^ Static ^Readonly Keywords

请记住,它不会阻止您将事物重新分配到这些插槽中,但它与 C# 所能提供的一样固定,除了每次都创建一个属性或返回一个新数组。

于 2013-04-12T00:26:42.350 回答
3

它不起作用,因为这是对const关键字的限制。

来自MSDN

const 关键字用于修改字段或局部变量的声明。它指定字段或局部变量的值是常数,这意味着它不能被修改。

常量表达式是可以在编译时完全计算的表达式。因此,引用类型常量的唯一可能值是string和 null

如果您尝试定义一个无法更改的数组,也许您应该使用readonly关键字,它将对字段或局部变量的更改限制在声明或构造函数中。

于 2013-04-12T00:28:39.293 回答
2

常量在编译时进行评估。数组是引用类型,创建引用类型的唯一方法是使用new关键字(在您的代码中隐含)。

new不能在常量表达式中使用,因为它不能在编译时计算。

请参阅 MSDN: http: //msdn.microsoft.com/query/dev11.query ?appId=Dev11IDEF1&l=EN-US&k=k(CS0134);k(TargetFrameworkMoniker-.NETFramework,Version%3Dv4.5)&rd=true

于 2013-04-12T00:28:55.860 回答