Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Declaring a long constant byte array

I have a long byte array that I need to declare in my C# code. I do something like this:

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

But I get an error that the const array may be initialized only with nulls.

If I change const to static it compiles, but the question I have is this -- when I declare it as public static byte[] gLongByteArray it won't be initialized every time my app loads, right? In that case the gLongByteArray variable will simply point to an array that is defined in the compiled exe/dll file that loads into memory. The reason I'm asking is because this array is pretty long and I don't want my program to waste CPU cycles on loading it every time the app starts, or worse, this class is referenced...

like image 647
ahmd0 Avatar asked Mar 21 '13 23:03

ahmd0


3 Answers

Compile-time constants (those declared with the const keyword) are severely restricted. No code must be executed to get such a constant, or otherwise it could not be a compile-time constant. const constants are static by default.

If you want to create a constant and you cannot use a compile-time constant, you can use static readonly instead:

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

The static keyword ensures it is initialized only once, and part of the declaring type (and not each instance). The readonly keyword ensures the longByteArray variable cannot be changed afterwards.

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

Warning: An array is mutable, so in the above code I can still do this:

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

To prevent that, make the type not an array but a read-only collection interface, such as IEnumerable<T> or IReadOnlyList<T>, or even better a read-only collection type such as ReadOnlyCollection<T> which doesn't even allow modification through casting.

public static readonly IReadOnlyList<byte> longByteArray = new byte[] { 1, 2, 3, 4, 5 };
like image 103
Daniel A.A. Pelsmaeker Avatar answered Sep 30 '22 14:09

Daniel A.A. Pelsmaeker


You can't make a const array. According to the documentation:

User-defined types, including classes, structs, and arrays, cannot be const.

You'd have to declare it as a static readonly field like this

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

Of course, there's nothing to stop someone from overwritting your array elements at run-time, like this:

Definitions.gLongByteArray[0] = 0xFF; 

You'd have to use one of the built in collections that @Virtlink suggests or create your own custom readonly array class to prevent that (example).

like image 29
p.s.w.g Avatar answered Sep 30 '22 14:09

p.s.w.g


Write all content to a file and embed as resource!

like image 24
IlPADlI Avatar answered Sep 30 '22 13:09

IlPADlI