C#で定数配列を使いたい場合はどうすればよいのか調べたので記載しておく。
const int[] arr = new int[] { 1, 2, 3 };
上記は右辺が定数式でないのでコンパイルエラーとなる。
private static readonly int[] arr = new int[]{ 1, 2, 3 };
上記のようにメンバー変数にしてreadonlyキーワードを付けてみる。これはコンパイルエラーとはならず実行できるが、以下のとおり配列の要素が読み取り専用になるのではなく、配列参照 arr が読み取り専用になるので使えない。
static void Main(string[] args)
{
for (int i = 0; i < arr.Length; i++)
{
Console.WriteLine(arr[i]);
}
arr[1] = 4; //要素は変更可能
arr = new int[] { 4, 5, 6 }; //コンパイルエラー
}
System.Collections.ObjectModel名前空間に ReadOnlyCollection<T> という配列の要素を読み取り専用にしてくれるラッパークラスがある。readonlyキーワードを付けて定義すると、配列の要素も配列参照も変更不可となる。ただしreadonlyキーワードを付けてもコンストラクタ内では配列参照を変更できるので注意する。
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleAppConstArray
{
class Program
{
private static readonly ReadOnlyCollection<int> arrConst = Array.AsReadOnly<int>(new int[] { 1, 2, 3 });
static void Main(string[] args)
{
for (int i = 0; i < arrConst.Count; i++)
{
//配列と同じく添字で要素にアクセスできる
Console.WriteLine(arrConst[i]);
}
//①要素を変更しようとするとコンパイルエラー
arrConst[1] = 99;
//②オブジェクト参照を変更しようとするとコンパイルエラー
arrConst = Array.AsReadOnly<int>(new int[] { 4, 5, 6 });
Console.ReadKey();
}
}
}

ReadOnlyCollection クラス (System.Collections.ObjectModel)
読み取り専用のジェネリック コレクションの基本クラスです。

Array.AsReadOnly(T[]) メソッド (System)
指定した配列をラップする読み取り専用のラッパーを作成します。
コメント