Объявление длинного константного байтового массива

У меня есть длинный байтовый массив, который мне нужно объявить в моем коде С#. Я делаю что-то вроде этого:

public static class Definitions
{
    public const byte[] gLongByteArray = new byte[] { 
        1, 2, 3,
        //and so on
    };
}

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

Если я сменил const на static, он скомпилируется, но вопрос у меня есть - когда я объявляю его как public static byte[] gLongByteArray, он не будет инициализироваться каждый раз, когда загружается мое приложение, верно? В этом случае переменная gLongByteArray будет просто указывать на массив, который определен в скомпилированном файле exe/dll, который загружается в память. Причина, по которой я спрашиваю, заключается в том, что этот массив довольно длинный, и я не хочу, чтобы моя программа теряла процессорные циклы при загрузке его каждый раз, когда приложение запускается, или, что еще хуже, этот класс ссылается...

Ответ 1

Константы времени компиляции (те, которые указаны с ключевым словом const) строго ограничены. Для получения такой константы код не должен выполняться, иначе он не может быть константой времени компиляции. Константы const по умолчанию static.

Если вы хотите создать константу, и вы не можете использовать константу времени компиляции, вы можете использовать static readonly вместо:

public static readonly byte[] longByteArray = new byte[] { 1, 2, 3, 4, 5 };

Ключевое слово static гарантирует, что оно инициализируется только один раз и часть типа объявления (а не каждого экземпляра). Ключевое слово readonly гарантирует, что переменная longByteArray не может быть изменена впоследствии.

Definitions.longByteArray = new byte[] { 4, 5, 6 };   // Not possible.

Предупреждение: массив изменен, поэтому в приведенном выше коде я все еще могу сделать это:

Definitions.longByteArray[3] = 82;                    // Allowed.

Чтобы предотвратить это, сделайте тип не массивом, а интерфейсом коллекции только для чтения, например IEnumerable<T> или IReadOnlyList<T> или даже лучше тип коллекции только для чтения, например ReadOnlyCollection<T>, который даже не допускает модификации при кастинге.

public static readonly IReadOnlyList<byte> longByteArray = new byte[] { 1, 2, 3, 4, 5 };

Ответ 2

Вы не можете создать массив const. В соответствии с документация:

Пользовательские типы, включая классы, структуры и массивы, не могут быть const.

Вам нужно объявить его как статическое поле readonly, подобное этому

public static class Definitions
{
    public static readonly byte[] gLongByteArray = new byte[] { 
        1, 2, 3,
        //and so on
    };
}

Конечно, нет ничего, чтобы помешать кому-либо перезаписывать элементы массива во время выполнения, например:

Definitions.gLongByteArray[0] = 0xFF; 

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

Ответ 3

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

Ответ 4

Записать весь контент в файл и вставить в качестве ресурса!