A readonly field cannot be assigned to の原因と直し方
readonly修飾子を付けたフィールドを、コンストラクタや初期化子以外の場所で書き換えようとすると出るコンパイルエラーです。
エラーメッセージの読み方
Program.cs(5,9): error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
Program.cs- ファイル名
5- 行番号
9- 列番号 — この位置でコンパイラが解析に失敗しました
CS0191- エラーコード — 検索するとMicrosoftの解説ページが見つかります
A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)- 内容 — 期待していたもの、または受け付けられなかったもの
このエラーが出る典型パターン
パターン1
1 class Config { 2 public readonly int MaxUsers = 100; 3 public int CurrentUsers = 0; 4 public void Reset() { 5 MaxUsers = 50; ^ 6 } 7 } 8 class Program { 9 static void Main(string[] args) { 10 Config c = new Config(); 11 c.Reset(); 12 System.Console.WriteLine(c.CurrentUsers); 13 } 14 }
Program.cs(5,9): error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
readonlyなフィールドはコンストラクタ以外から代入できません。書き換えたい値は普通のフィールドにする必要があります。
直し方: MaxUsers を CurrentUsers にします。
広告
広告スロット(未設定)
パターン2
1 class Product { 2 public readonly string Id = "P-1"; 3 public int Stock = 0; 4 public void Restock() { 5 Id = 20; ^ 6 } 7 } 8 class Program { 9 static void Main(string[] args) { 10 Product p = new Product(); 11 p.Restock(); 12 System.Console.WriteLine(p.Stock); 13 } 14 }
Program.cs(5,9): error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
Idは商品を識別するための値なので変更させたくありません。readonlyにすることで代入をコンパイル時に防げます。
直し方: Id を Stock にします。
パターン3
1 class GameConfig { 2 public readonly int MaxLevel = 99; 3 public int CurrentLevel = 1; 4 public void LevelUp() { 5 MaxLevel = CurrentLevel + 1; ^ 6 } 7 } 8 class Program { 9 static void Main(string[] args) { 10 GameConfig g = new GameConfig(); 11 g.LevelUp(); 12 System.Console.WriteLine(g.CurrentLevel); 13 } 14 }
Program.cs(5,9): error CS0191: A readonly field cannot be assigned to (except in a constructor or init-only setter of the type in which the field is defined or a variable initializer)
上限値のような変わってほしくない値をreadonlyにしておくと、誤って書き換えるコードをコンパイル時に検出できます。
直し方: MaxLevel を CurrentLevel にします。
よくある誤解
readonlyはコンストラクタの中でも常に書けるわけではなく、そのフィールドを定義した型のコンストラクタからしか書けません。継承先のコンストラクタからも書けない点に注意が必要です。
まとめ
A readonly field cannot be assigned toは上級でつまずきやすい項目です。上の3パターンを実際に手で直すと、エラーメッセージのどこを読めばよいかが掴めます。