Const Arrays in Functions

hfaun 1 Reputation point
2022-08-23T16:27:54.83+00:00

I want to do something like this in C#

static const WORD MyArray[ArrayLength] = { 0, 1, 2, 3, 4 };

It is my understanding that in C# there isn't a complete equivalent. Arrays are always created dynamically but one can declare them as readonly. The issue I am having is that this is always for class members so I need a public, private, etc modifier. However, I want to have those readonly arrays just in a function. How do I do that?

Developer technologies C#
{count} votes

2 answers

Sort by: Most helpful
  1. Michael Taylor 60,161 Reputation points
    2022-08-23T17:20:51.51+00:00

    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.

    0 comments No comments

  2. Bruce (SqlWork.com) 77,686 Reputation points Volunteer Moderator
    2022-08-23T18:43:29.703+00:00

    as array are objects they can not be created at compile time. for some reason you can not declare a static in a method, must be done outside, so the best you can do is make it private in the containing class:

    // static class  
    public static class MyStaticClass  
    {  
         private static readonly int[] _myArray = new int[] {1,2,3,4,5};  
      
         public static int MyMethod(int i)  
         {  
               return _myArray[i];  
         }  
    }  
      
    // instance class  
    public class MyClass  
    {  
         private static readonly int[] _myArray = new int[] {1,2,3,4,5};  
      
         public int MyMethod(int i)  
         {  
               return _myArray[i];  
         }  
      
         public static int MyMethod2(int i)  
         {  
               return _myArray[i];  
         }  
    }  
      
    
    0 comments No comments

Your answer

Answers can be marked as Accepted Answers by the question author, which helps users to know the answer solved the author's problem.