Вопрос по readonly, c#, static, const – Объявление константного двойного [] в C #? [Дубликат]

45

This ques#ion already has an answer here:

Why does C# limi# #he se# of #ypes #ha# can be declared as cons#? 6 answers

У меня есть несколько констант, которые я использую, и мой план состоял в том, чтобы поместить их в константный массив значений типа double, однако компилятор меня не допустил.

Я попытался объявить это так:

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

Затем я решил объявить его статическим только для чтения:

s#a#ic readonly double[] arr = { 1, 2, 3, 4, 5, 6, 7, 8, 9};

Однако вопрос остается. Почему компилятор не позволяет мне объявлять массив значений cons#? Или так, а я просто не знаю как?

Ваш Ответ

6   ответов
1

ошибка компилятора точно скажет, почему вы не можете это сделать:

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

3

зачем вам нужно было сделать его постоянным или только для чтения. Если вы действительно хотите сделать весь массив неизменным, то простое ключевое слово константы / только для чтения вам не поможет, и, что еще хуже, оно также может отвлечь вас от неправильного пути.

Для любых неизменяемых ссылочных типов делайте их только для чтения, что означает, что вы никогда не сможете переназначить переменнуюitself, но содержание все еще изменчиво. Смотрите ниже пример:

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 (); предоставит вам список содержимого, предназначенный только для чтения.

39

Из 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.

2

Проблема состоит в том, что вы объявляете постоянный массив double, а не массив постоянных double. Я не думаю, что есть способ получить массив констант из-за способа работы массивов в C #.

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, должно быть ... const. Каждый ссылочный тип не является константой, а массив является ссылочным типом.

Решение, которое показало мое исследование, заключалось в использовании статического чтения только. Или, в вашем случае с фиксированным числом двойников, присвойте всем индивидуальный идентификатор.

Edit(2): Небольшой sidenode, каждый тип может быть использован const, но назначенное ему значение должно быть const. Для ссылочных типов единственное, что вы можете назначить, это null:

static const double[] arr = null;

Но это совершенно бесполезно. Строки являются исключением, они также являются единственным ссылочным типом, который может использоваться для аргументов атрибута.

@Jon: Строки неизменны.
Точно, как здесь:gamedev.net/community/forums/topic.asp?topic_id=276930
Право на. Увидеть:msdn.microsoft.com/en-us/library/ms228606.aspx
Строка является ссылочным типом, и вы можете иметь постоянные строки ...
Пояснение: я имею в виду, что, хотя строки являются ссылочными типами, поскольку они являются неизменяемыми, имеет смысл, что они могут быть постоянными.
9

ры, свойства и т. Д., Чтобы гарантировать, что содержимое массива не будет изменено. Возможно, вам придется пересмотреть публичную сторону вашего класса.

Просто чтобы указать, хотя ... Статические только для чтения

Это совершенно верно, а не то, что вы хотели:

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

Вам нужно будет найти другие способы защиты вашего массива.

Похожие вопросы