連載:[完全版]究極のC#プログラミングChapter13 自動実装と自動定義川俣 晶2010/02/17 |
|
|
13.10 オブジェクト初期化子の本質とは?
オブジェクトのフィールド/プロパティを初期化する手段をまとめると、おおむね次の3つに分けられる。
- フィールドの宣言時に初期値を指定する
- コンストラクタで書き込む
- オブジェクト初期化子を使う
これらの性質の違いを把握することは、オブジェクト初期化子を使いこなすうえで重要なポイントになる。
まず、初期化される順番だが、上記の順に実行される。オブジェクト初期化子は最後に実行されるので、クラス内でどのような初期化を行っていても、最終的にそれらは上書きされ、オブジェクト初期化子で指定された値で確定する。
次のリスト13.22を実行すると、そのことが確認できるだろう。
| |
リスト13.22 初期化の順番を調べる |
これらの手段間の相違はほかにもある。実は、オブジェクト初期化子は、privateなどのフィールドやreadonlyのフィールドなどは初期化できない(リスト13.23参照)。
| |
リスト13.23 初期化できないケース |
なぜ、“フィールドの宣言時に初期値を指定する”、あるいは“コンストラクタで書き込む”のと違って、“オブジェクト初期化子を使う”ことでprivateやreadonlyのフィールドを初期化できないのだろうか?
その理由は、オブジェクト初期化子が、その名に反して「オブジェクト自身の初期化段階」の中で実行されないことにある。オブジェクト初期化子とは、オブジェクト外部に存在するものであり、オブジェクトの初期化が完了するまではオブジェクトに手出しができないのである。そして、外部からオブジェクトに手出しができる段階に入ると、もはやreadonlyのフィールドを書き換えることは許されない。また、あくまで外部から書き込みを行う立場であるから、privateなフィールドに手出しできないのも当然の成り行きといえる。
しかし、これは悪いことばかりではない。オブジェクト初期化子がオブジェクトの外部に存在するということは、オブジェクト初期化子が存在する場所から利用できる資源はすべて利用できるからだ。
たとえば、次のリスト13.24は、オブジェクト初期化子を記述したメソッド(Mainメソッド)の引数を利用して初期化を行っている。
| |
リスト13.24 実行ファイルのパラメータの数で初期化する |
オブジェクト初期化子なしで同様の値によりフィールドTargetを初期化するには、コンストラクタ経由で値を送り込むか、あるいはオブジェクト生成後に明示的にTargetの値を書き換えるしかない。
INDEX | ||
[完全版]究極のC#プログラミング | ||
Chapter13 自動実装と自動定義 | 1.13.1 ラムダ式を使ったダーティテク―refの代役 | |
2.13.2 自動実装プロパティ | ||
3.13.3 自動実装プロパティのアクセス制御 | ||
4.13.4 読み出し専用、書き込み専用はない | ||
5.13.5 “名無し”のクラス―匿名型 | ||
6.13.6 匿名型の等価性 | ||
7.13.7 匿名型の簡易記法 | ||
8.13.8 匿名型の使用目的 | ||
9.13.9 オブジェクト初期化子 | ||
10.13.10 オブジェクト初期化子の本質とは? | ||
11.13.11 コレクションはreadonlyでも初期化できる | ||
12.13.12 オブジェクト初期化子の使用例/練習問題 | ||
「[完全版]究極のC#プログラミング」 |
- 第2回 簡潔なコーディングのために (2017/7/26)
ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている - 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう - 第1回 明瞭なコーディングのために (2017/7/19)
C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える - Presentation Translator (2017/7/18)
Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
|
|