45

我有几个我使用的常量,我的计划是将它们放在一个双精度的 const 数组中,但是编译器不会让我这样做。

我试过这样声明:

const double[] arr = {1, 2, 3, 4, 5, 6, 73, 8, 9 };

然后我决定将其声明为静态只读:

static readonly double[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9};

然而问题仍然存在。为什么编译器不让我声明一个 const 值数组?或者会,我只是不知道怎么做?

4

6 回答 6

45

这可能是因为

static const double[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9};

其实和说的一样

static const double[] arr = new double[]{ 1, 2, 3, 4, 5, 6, 7, 8, 9};

分配给 const 的值必须是... const。每个引用类型都不是常量,数组是一种引用类型。

我的研究表明,解决方案是使用静态只读。或者,在您的情况下,使用固定数量的双打,给所有东西一个单独的标识符。


编辑(2): 一个小sidenode,每个类型都可以用const,但是赋给它的值必须是const。对于引用类型,您唯一可以分配的是 null:

static const double[] arr = null;

但这完全没用。字符串是例外,它们也是唯一可用于属性参数的引用类型。

于 2009-07-10T14:25:08.110 回答
39

来自 MSDN ( http://msdn.microsoft.com/en-us/library/ms228606.aspx )

常量表达式是可以在编译时完全计算的表达式。因为创建引用类型 [an array] 的非空值的唯一方法是应用 new 运算符,并且因为 new 运算符不允许在常量表达式中,所以引用常量的唯一可能值 -字符串以外的类型为空。

于 2009-07-10T14:26:31.633 回答
9

在 C# 中没有办法拥有一个 const 数组。您需要使用索引器、属性等来确保不修改数组的内容。您可能需要重新评估班级的公共方面。

只是要指出...静态只读-IS NOT CONST-

这是完全有效的,而不是您想要的:

class TestClass
{
    public static readonly string[] q = { "q", "w", "e" };
}

class Program
{
    static void Main( string[] args )
    {
        TestClass.q[ 0 ] = "I am not const";
        Console.WriteLine( TestClass.q[ 0 ] );
    }
}

您将需要寻找其他方法来保护您的阵列。

于 2010-04-22T18:42:57.017 回答
3

我不知道您为什么需要将其设为常量或只读。如果你真的想让整个数组不可变,那么简单的常量/只读关键字对你没有帮助,更糟糕的是,它还可能把你引向错误的方向。

对于任何非不可变引用类型,将它们设为只读意味着您永远不能重新分配变量本身,但内容仍然是可变的。请参见下面的示例:

readonly double[] a = new double[]{1, 2, 3};
...
a = new double[] {2,3}; // this won't compile;
a[1] = 4; // this will compile, run and result the array to {1, 4, 3}

根据您的上下文,可能有一些解决方案,其中之一是,如果您真正需要的是双列表, List a = new List() {1,2,3,4,5}.AsReadOnly(); 会给你一个内容只读的 double 列表。

于 2010-04-22T20:33:10.847 回答
2

问题是您要声明一个双精度常量数组,而不是一个常量双精度数组。由于数组在 C# 中的工作方式,我认为没有办法拥有一个常量数组。

于 2009-07-10T14:26:26.780 回答
1

编译器错误告诉你为什么你不能这样做:

“arr”的类型为“double []”。
字符串以外的引用类型的 const 字段只能用 null 初始化。

于 2009-07-10T14:25:26.813 回答