在C#中声明const double[]?

44

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

我尝试了这种声明方式:

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

然后我决定将其声明为 static readonly:

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

然而问题依然存在。为什么编译器不允许我声明一个由常量值组成的数组?还是说它会允许,只是我不知道如何声明?

6个回答

44

这可能是因为

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)赋值后必须保持为常量。所有引用类型都不是常量,而数组是引用类型。

我的研究表明,解决方法是使用 static readonly。或者,在您的情况下,如果有一组固定数量的双精度数,请给每个数分配一个唯一的标识符。


编辑(2): 需要注意的是,每种类型都可以使用 const,但所赋的值必须是常量。对于引用类型,你只能将其赋值为 null:

static const double[] arr = null;

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


没错。请参见:http://msdn.microsoft.com/zh-cn/library/ms228606.aspx - Ray Vernagus
准确地说,就像这里一样:http://www.gamedev.net/community/forums/topic.asp?topic_id=276930 - Dykam
4
字符串(String)是一种引用类型,您可以拥有常量字符串。在Java中,字符串是不可变的,这意味着一旦创建了一个字符串,它的值就不能被更改。 - Jon Skeet
1
澄清:我的意思是,虽然字符串是引用类型,但由于它们是不可变的,因此它们可以是常量。 - Sean
是的,我知道...但它指出了“数组是引用”的问题。 数组的内容并不重要,是吗? - Dykam

38

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

常量表达式是能够在编译时完全评估的表达式。由于创建引用类型[数组]的非空值的唯一方法是应用new运算符,而且因为new运算符在常量表达式中不允许使用,因此除了字符串类型之外的引用类型常量的唯一可能值是null。


9

在C#中没有办法创建const数组。您需要使用索引器、属性等来确保数组内容不被修改。您可能需要重新评估类的公共部分。

只是想指出...静态只读变量(Static readonly)-不等同于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 ] );
    }
}

你需要找到其他保护数组的方法。

3
我不知道为什么您需要将其设置为常量或只读。如果您真的想使整个数组不可变,则简单的constant/readonly关键字是无法帮助您的,更糟糕的是,它可能会让您走上错误的道路。
对于任何非不可变引用类型,仅将它们设置为只读意味着您永远不能重新分配变量本身,但内容仍然是可变的。请参阅下面的示例:
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}

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


2
问题在于你声明了一个常量双精度数组,而不是一个常量双精度数组的数组。我认为由于C#中数组的工作方式,不存在一种方法可以拥有常量数组。

1

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

'arr'是类型为'double[]'的。
引用类型的const字段只能用null初始化。


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