読者です 読者をやめる 読者になる 読者になる

プログラミングMicrosoft .NET Framework 第2版

book C#

今年の4月に年間50冊読書するぞと目標を立ててから、薄いビジネス書ばかり読んでいたのですが、意外と読めることが分かったので、最近は厚い技術書に挑戦しています。

まずはコレ。

プログラミングMicrosoft .NET Framework 第2版 (マイクロソフト公式解説書)

プログラミングMicrosoft .NET Framework 第2版 (マイクロソフト公式解説書)

700ページもあるので、読み切るのに1ヶ月くらいかかりましたが、それくらい時間をかけても読む価値のある本です。
.NET Framework上でプログラミングしている人は必読ですね。


僕は気になるところに付箋を貼りながら読んでいたのですが、気がついたら100箇所以上に付箋が・・・
読み終えた後に付箋の箇所を抜き出して、レバレッジメモを作ったのですが、かなりの労力を要しました。


その中でも特に興味深かったのが以下の項目です。

  • JITコンパイラの仕組み。始めて実行する処理は、JITコンパイラがネイティブコードにコンパイルするが、 2回目以降は、コンパイル済みのコードを呼び出す。また、CPUに依存した特殊な命令を利用するため、アンマネージコードよりもパフォーマンスが高くなることもある。
  • 引数は汎用的な型にすべき。Listよりも、IEnumerableやIListに、FileStreamよりもStreamにすべきである。逆に戻り値は強い型づけをすること。
  • この著者は、プロパティに対しては批判的。なぜならばプロパティはフィールドのように見えるが、例外を出したり、実行に時間がかかる可能性があったり、副作用を持つ場合があるなど、フィールドとふるまいが異なり混乱の原因となるため。
  • 戻り値が配列の参照を返すメソッドにおいて、配列の要素がない場合は、長さ0の配列を返すべき。
  • JITコンパイラを過少評価して、賢いコードを書くと、パフォーマンスに悪影響が出るから注意せよというのも面白い。例えば、以下のように書くと、Lengthプロパティを何度も呼ぶように思えるが、JITコンパイラが変数にLengthの値を入れて、変数をチェックするコードが出力される。
   int[] a = new int[10];
   for( int i = 0; i < a.Length; i++ ) {
     // a[i]へのアクセス
   }
  • ジェネリックインタフェースの利点として、コンパイル時のタイプセーフティが得られるというのは知っていたが、ボックス化が発生しないため、パフォーマンスが向上するというのは知らなかった。
  • カスタム属性や、null許容型というものを初めて知った。
  • 例外の適切な使い方も、とても参考になる。
    • メソッドの実引数に関する例外は、ArgumentException系を継承すると良い。
    • クラスライブラリの一部として提供される型がすべての例外を補足して飲み込んでしまうようなことは、どんな場合であっても、絶対にあってはならない。
    • 不正な例外を補足して、そのまま動作し続けるよりも、例外を未処理のままにしてアプリケーションが強制終了した方がよい。
    • 未処理の例外はコードをテストしているときに発見され、そのバグを修正することで、堅牢なコードが得られる。
  • ジェネレーショナルガベージコレクタの仕組みも面白い。以下の仮説に従って効率の良いメモリ管理をおこなっている。
    • オブジェクトが新しいほど、その寿命も短い。
    • オブジェクトが古いほど、その寿命は長くなる。
    • ヒープの一部を回収する方が、ヒープ全体で回収作業をおこなうよりも速い。
  • コンテキストスイッチのオーバーヘッドはかなり大きい。専用のスレッドを利用するよりも、スレッドプールを利用すべきである。
  • 非同期プログラミングモデル(Asynchronous Programming Model : APM)というパターンがある。BeginXxxやEndXxxというメソッドを用いたもの。終了待機の方法が3つある。


こういう良書を読むと、自分のプログラミングの品質が一段アップするように感じますね。(C++のときは、Effective C++ 原著第3版 (ADDISON-WESLEY PROFESSIONAL COMPUTING SERIES)を読んだときに同様に感じました。)