You cannot have const arrays in C#. That is one of the limitations. You can make the variable that stores an array readonly so it cannot be pointed to something else. The size of the array is fixed at creation time (it is an attribute of the type, not like C++) so it also cannot be resized without creating a new array. But the contents of an array is writable and there is nothing you can do about it.
To be honest this shouldn't be a big deal. Let's take your example (I'm assuming this is a field in a class).
//Note I'm using `int` here but technically `WORD` maps to `ushort`.
readonly int[] MyArray = new int[] { 0, 1, 2, 3, 4 };
That will work just fine. The array field is writable either via the field initializer or a constructor but is read only after that. It cannot be constant because arrays are ref types and aren't actually instantiated until runtime. Constants (like most every language that uses them) must be primitives that are baked into the code at compile time.
This will fail (outside a constructor).
MyArray = new int[] { 10, 11, 12, 13, 14 };
But you can change any element within it because array elements are always mutable.
MyArray[3] = 20;
There is nothing you can do about this as it is by design. But if you look at why you're using an array things start to make sense. An array is just a collection of values. They are equivalent to a bunch of variables being defined (e.g. value1
, value2
). As such locking them down isn't terribly useful. Let's look at a use case.
public int[] GetValues () { return MyArray; }
int[] values = GetValues();
values[0] = 20; //Just changed MyArray's element
As a return value you don't know or care what somebody does with your array as they now have a copy in their own variable. Hence they could change your array elements. So you really shouldn't return back an array from a method (or property for that matter) if you don't want the array to be changed. Arrays are best used to store sets of data that you then pass back to the caller and they can do whatever they want.
If you need an immutable list of values then use IEnumerable<T>
or perhaps IReadOnlyList<T>
. These interfaces indicate that the values can be enumerated (or used as a list) but are otherwise immutable. In fact array implements the interface so often we use an array as the backing store.
IEnumerable<int> GetValues () { return MyArray; }
var values = GetValues();
values[0] = 10; //Compiler error, can only enumerate the values
If you want to support array-like syntax then use IReadOnlyList<T>
instead. This adds support for array indexing but still doesn't allow modifications.
In my experience you should probably consider using List<T>
over arrays in all cases unless performance is a really, really big concern and the array size is probably never going to change. If you're using IEnumerable<T>
or IReadOnlyList<T>
then returning the list (instead of an array) is identical, callers cannot modify the values and you get the same behavior.