【问题标题】:Const multi-dimensional array initializationconst多维数组初始化
【发布时间】:2013-04-04 08:58:51
【问题描述】:

为什么以下工作有效?

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(?)。如果它是常量且为null,它将如何初始化?

【问题讨论】:

    标签: c# arrays constants


    【解决方案1】:

    如果我没记错的话,它是 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=true

    编辑编辑: 如果您需要将静态表铆接到代码上,并且在初始化后绝不让任何人更改它,那么可以使用 readonly 关键字:

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

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

    【讨论】:

    • 我只能说哇。除了最明显的以外,这迫使我想方设法制作常量整数表。
    • @user2255673 如果你正在寻找类似 C++ 的 const * const 之类的东西,你不会在 C# 中找到它。
    • @user2255673 是的,这很不幸。但是,您可以制作静态整数表并对其进行操作,我已经编辑了答案以向您展示。
    • @user2255673 请注意,这没有什么“恒定”的;任何一段代码都可以随意替换或更改元素。
    • @ThePhD 不不,readonly 只会阻止重新分配一个全新的 int[,] 数组引用。没有什么能阻止代码执行i[0, 0] = 9999
    【解决方案2】:

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

    来自MSDN

    const 关键字用于修改字段或本地的声明 多变的。它指定字段的值或本地 变量是常量,不能修改。

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

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

    【讨论】:

    • 请注意,readonly 只会使数组 reference 成为只读。对于任何引用数组的人来说,内容仍然可以通过索引改变。
    【解决方案3】:

    常量在编译时计算。数组是引用类型,创建引用类型的唯一方法是使用 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

    【讨论】:

    • 请注意,字符串有一点需要注意,因为字符串是引用类型,但具有特殊的支持,支持将它们作为常量从底层 IL 代码加载。
    • 确实,我可能应该提到这一点。
    猜你喜欢
    • 1970-01-01
    • 2015-08-01
    • 1970-01-01
    • 2011-04-03
    • 2015-07-20
    • 2015-02-26
    相关资源
    最近更新 更多