45

I have several constants that I use, and my plan was to put them in a const array of doubles, however the compiler won't let me.

I have tried declaring it this way:

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

Then I settled on declaring it as static readonly:

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

However the question remains. Why won't compiler let me declare an array of const values? Or will it, and I just don't know how?

David Božjak
  • 16,887
  • 18
  • 67
  • 98

6 Answers6

45

This is probably because

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

is in fact the same as saying

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

A value assigned to a const has to be... const. Every reference type is not constant, and an array is a reference type.

The solution, my research showed, was using a static readonly. Or, in your case, with a fixed number of doubles, give everything an individual identifier.


Edit(2): A little sidenode, every type can be used const, but the value assigned to it must be const. For reference types, the only thing you can assign is null:

static const double[] arr = null;

But this is completely useless. Strings are the exception, these are also the only reference type which can be used for attribute arguments.

Pang
  • 9,564
  • 146
  • 81
  • 122
Dykam
  • 10,190
  • 4
  • 27
  • 32
  • Right on. See: http://msdn.microsoft.com/en-us/library/ms228606.aspx – Ray Vernagus Jul 10 '09 at 14:26
  • Exactly, like here: http://www.gamedev.net/community/forums/topic.asp?topic_id=276930 – Dykam Jul 10 '09 at 14:27
  • 4
    String is a reference type, and you can have constant strings... – Jon Skeet Jul 10 '09 at 14:27
  • 1
    Clarification: my meaning is that while strings are reference types, since they're immutable it makes sense that they can be constant. – Sean Jul 10 '09 at 14:32
  • Yeah, I know... but it pointed out the `array is a reference` problem. The content of the array doesn't really matter, does it? – Dykam Jul 10 '09 at 14:40
39

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

A constant-expression is an expression that can be fully evaluated at compile-time. Because the only way to create a non-null value of a reference-type [an array] is to apply the new operator, and because the new operator is not permitted in a constant-expression, the only possible value for constants of reference-types other than string is null.

JohnFx
  • 34,542
  • 18
  • 104
  • 162
9

There is no way to have a const array in C#. You need to use indexers, properties, etc to ensure the contents of the array are not modified. You may need to re-evaluate the public side of your class.

Just to point out though... Static readonly -IS NOT CONST-

This is perfectly valid and not what you were wanting:

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 ] );
    }
}

You will need to find other ways to protect your array.

Karl Strings
  • 1,017
  • 9
  • 22
3

I don't know why you needed to make it either constant or readonly. If you really want to make the whole array immutable, then a simple constant/readonly keyword will not help you, and what's worse is, it might also divert you to the wrong way.

For any non-immutable reference types, make them readonly only means you can never re-assign the variable itself, but the content is still changeable. See below example:

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}

Depending on your context, there might be some solutions, one of them is, if what you really need is a list of double, List a = new List() {1,2,3,4,5}.AsReadOnly(); will give you a content-readonly list of double.

louis
  • 79
  • 3
2

The problem is that you're declaring a constant array of double, not an array of constant doubles. I don't think there is a way to have an array of constants due to the way arrays work in C#.

Yohnny
  • 86
  • 4
1

The compiler error tells you exactly why you can't do it:

'arr' is of type 'double[]'.
A const field of a reference type other than string can only be initialized with null.

LukeH
  • 263,068
  • 57
  • 365
  • 409