読み取り専用ローカル変数の提案が復活したのは遠い昔ではない。これは 読み取り専用参照型の提案よりもはるかに控えめな機能だが、これら2つは相補的だ。
読み取り専用ローカル変数の基本的な文法は、単に型名の前にreadonly
キーワードを追加するというものだ。これはローカル変数にとって、フィールドに作用するのと本質的に同じ方法で作用する。パラメーターにもreadonly
キーワードを適用できるようになるだろう。
手短に、readonly
変数の代わりにlet
を使用することができる。let
キーワードは複数の理由で選ばれた。
- C# LINQ表現において読み取り専用な範囲変数のための唯一のキーワードである
- F#(と他の言語)において読み取り専用なローカル変数を宣言するためのキーワードでもある
val
など、この役割のためのよくあるキーワードと視覚的に区別しやすい
基本的なユースケースは、何かを伝えることだ。コードを読んでいる人に、そのローカル変数は一度セットされてから値が変わらないことを伝えてくれる。
この提案では、匿名関数や非同期関数を使用する際の防御的プログラミングにも役立つと述べられている。よくある誤りは、ローカル変数を囲うクロージャーを作成し、そのクロージャーを別スレッドに渡すというものだ。ローカル変数で競合状態が起こりうるにもかかわらず、ほとんどの開発者がそのことについて考えていないため、競合状態の検知は困難だ。変数を読み取り専用であるとマークをつけることにより、コンパイラーはクロージャー内での再代入を防ぐ。
読み取り専用変数をref
またはout
引数として関数に渡すことはできない。しかし提案が実装されたら、readonly ref
引数として渡すことは可能になるかもしれない。
警告: 構造体変数をローカルやパラメーターとして読み取り専用で宣言した場合、メソッドを呼ぶ際は必ずコンパイラーが暗黙的にコピーを作成する。integerのような小さな構造体にとってはこれは問題ではないが、大きな構造体にとっては、些細ではないコピーのコストが問題となりうる。可能な修正として、読み取り専用参照型変数の提案 における"読み取り専用構造体”を参照されたい。
設計のオープンな問題
let x
が即時の割り当てを求める一方で、 readonly Type x
も同様にすべきか。
引数について、宣言で引数を要求することによって、その引数が何だったかが容易にわかるようになる。加えて、提案の全体がシンプルになる。
即時の割り当てを求めることに対する議論は、可読性についても同様だ。条件付き表記(x = a ? b : c)
を使用するとコードが読みづらくなることがある。また、try-catchブロックをサポートする必要がある場合は機能しない
さらなる情報
Rate this Article
- Editor Review
- Chief Editor Action