Объявить массив const

Можно ли написать что-то похожее на следующее?

public const string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" }; 

Да, но вам нужно объявить его только для readonly а не const :

 public static readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" }; 

Причина в том, что const может применяться только к полю, значение которого известно во время компиляции. Инициализатор массива, который вы указали, не является постоянным выражением в C #, поэтому он создает ошибку компилятора.

Объявление его только для readonly решает эту проблему, потому что значение не инициализируется до времени выполнения (хотя оно гарантировано будет инициализировано до первого использования массива).

В зависимости от того, что вы в конечном итоге хотите достичь, вы также можете рассмотреть объявление enums:

 public enum Titles { German, Spanish, Corrects, Wrongs }; 

Вы можете объявить массив как readonly , но имейте в виду, что вы можете изменить элемент массива readonly .

 public readonly string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" }; ... Titles[0] = "bla"; 

Рассмотрите возможность использования enums, как предложил Коди, или IList.

 public readonly IList ITitles = new List {"German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly(); 

Вы не можете создать массив ‘const’, потому что массивы являются объектами и могут создаваться только во время выполнения, а сущности const решаются во время компиляции.

Вместо этого вы можете объявить свой массив как «readonly». Это имеет тот же эффект, что и const, за исключением того, что значение может быть установлено во время выполнения. Он может быть установлен только один раз, и после него значение readonly (т.е. const).

Для моих нужд я определяю static массив вместо невозможного const и он работает: public static string[] Titles = { "German", "Spanish", "Corrects", "Wrongs" };

Вы можете использовать другой подход: определить постоянную строку для представления вашего массива, а затем разбить строку на массив, когда вам это нужно, например

 const string DefaultDistances = "5,10,15,20,25,30,40,50"; public static readonly string[] distances = DefaultDistances.Split(','); 

Этот подход дает вам константу, которая может быть сохранена в конфигурации и преобразована в массив, когда это необходимо.

Аластер

С C # 6 вы можете написать это как:

 public static string[] Titles => new string[] { "German", "Spanish", "Corrects", "Wrongs" }; 

См. Также: C #: новый и улучшенный C # 6.0 (в частности, глава «Выражение функциональных функций и свойств»)

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

Для уточнения этот код такой же, как (или фактически сокращенное обозначение):

 public static string[] Titles { get { return new string[] { "German", "Spanish", "Corrects", "Wrongs" }; } } 

Обратите внимание, что существует недостаток этого подхода: новый массив фактически создается на основе каждой ссылки, поэтому, если вы используете очень большой массив, это может быть не самое эффективное решение. Но если вы повторно используете один и тот же массив (например, поместив его в частный атрибут), он снова откроет возможность изменить содержимое массива.

Если вы хотите иметь неизменяемый массив (или список), вы также можете использовать:

 public static IReadOnlyList Titles { get; } = new string[] { "German", "Spanish", "Corrects", "Wrongs" }; 

Но это все еще подвержено риску изменений, поскольку вы все равно можете вернуть его в строку [] и изменить содержимое следующим образом:

 ((string[]) Titles)[1] = "French"; 

Это способ сделать то, что вы хотите:

 using System; using System.Collections.ObjectModel; using System.Collections.Generic; public ReadOnlyCollection Titles { get { return new List { "German", "Spanish", "Corrects", "Wrongs" }.AsReadOnly();}} 

Это очень похоже на выполнение массива readonly.

Решение .NET Framework v4.5 +, которое улучшает ответ tdbeckett :

 using System.Collections.ObjectModel; // ... public ReadOnlyCollection Titles { get; } = new ReadOnlyCollection( new string[] { "German", "Spanish", "Corrects", "Wrongs" } ); 

Примечание. Учитывая, что коллекция концептуально постоянна, может иметь смысл сделать ее static чтобы объявить ее на уровне classа .

Вышесказанное:

  • Инициализирует неявное поле свойств свойства один раз с помощью массива.

    • Обратите внимание, что { get; } { get; } – то есть, объявляя только свойство getter – это то, что делает само свойство неявно доступным только для чтения (попытка совместить readonly с { get; } на самом деле является синтаксической ошибкой).

    • В качестве альтернативы вы можете просто опустить { get; } { get; } и добавьте readonly чтобы создать поле вместо свойства, как в вопросе, но выставлять публичные элементы данных как свойства, а не поля, является хорошей привычкой формироваться.

  • Создает массивную структуру (позволяющую индексированный доступ), которая действительно и надежна только для чтения (концептуально, постоянна, после создания), как по отношению к:

    • предотвращая модификацию коллекции (например, путем удаления или добавления элементов или путем замены коллекции в целом)
    • предотвращая модификацию отдельных элементов.
      (Даже косвенная модификация невозможна – в отличие от решения IReadOnlyList , где a (string[]) cast может использоваться для получения доступа на запись к элементам, как показано в полезном ответе mjepsen .
      Такая же уязвимость относится к интерфейсу IReadOnlyCollection , который, несмотря на свое сходство имени с classом ReadOnlyCollection , даже не поддерживает индексированный доступ, что делает его принципиально непригодным для предоставления доступа к массиву).

Если вы объявляете массив за интерфейсом IReadOnlyList, вы получаете постоянный массив с постоянными значениями, объявленными во время выполнения:

 public readonly IReadOnlyList Titles = new [] {"German", "Spanish", "Corrects", "Wrongs" }; 

Доступен в .NET 4.5 и выше.

Я считаю, что вы можете сделать это только для чтения.

Массивы, вероятно, являются одной из тех вещей, которые можно оценить только во время выполнения. Константы должны оцениваться во время компиляции. Попробуйте использовать «readonly» вместо «const».

В качестве альтернативы, чтобы обойти проблему, связанную с элементами, которая может быть изменена с помощью массива readonly, вместо этого вы можете использовать статическое свойство. (Отдельные элементы все равно могут быть изменены, но эти изменения будут сделаны только в локальной копии массива.)

 public static string[] Titles { get { return new string[] { "German", "Spanish", "Corrects", "Wrongs"}; } } 

Конечно, это не будет особенно эффективно, так как каждый раз создается новый массив строк.

Для полноты, теперь у нас также есть ImmutableArrays в нашем распоряжении. Это должно быть действительно неизменным:

 public readonly static ImmutableArray Tiles = ImmutableArray.Create(new[] { "German", "Spanish", "Corrects", "Wrongs" }); 

Требуется ссылка System.Collections.Immutable NuGet

https://msdn.microsoft.com/en-us/library/mt452182(v=vs.111).aspx

  • Как выводить сериализованные данные представления JSON в виде массива объектов, а не обертывать внешний объект?
  • Как отрезать массив в Excel VBA?
  • Сохранение заказа с помощью LINQ
  • Удалите повторяющиеся значения из массива JS
  • Массивы декодирования Swift JSONDecode терпят неудачу, если сбой одного элемента
  • Различие между емкостью списка массивов и размером массива
  • Как скопировать массив символов в C?
  • Java-массив с элементами более 4 ГБ
  • Как разрезать массив в Bash
  • c ++ array - выражение должно иметь постоянное значение
  • Определите, является ли JSON JSONObject или JSONArray
  • Давайте будем гением компьютера.