オライリー:プログラミングC# 第4版 メモ

プログラミングC#―C#2.0/.NET2.0/Visual Studio2005対応

プログラミングC#―C#2.0/.NET2.0/Visual Studio2005対応

プログラミング C# 第4版を最近スキャンしたのですが、以前読んだ時の付箋がたくさん貼ってありました。読み返してみたら今でも相当面白かったので、メモを淡々と書いてみます。

現在は第6版なので、以下のメモには現在の仕様と異なっている部分があるかもしれません。ご注意ください。

  • p26 値型(value type)と参照型(reference type)の説明
    • →地味に各章への伏線がはってある
  • p28 スタックとヒープ
    • コラムでスタックとヒープについての説明
  • p29 組み込み型同士の変換
    • "キャストとは「おい!コンパイラ!私は自分が何をやってるのかちゃんとわかってるよ」と伝えること"
  • p33 シンボル定数(const)
    • シンボル定数という呼び方
  • p36 列挙型の変換 cast
    • 指定しないと0から始まって1ずつ増える。途中指定するとそこから増える。
  • p45 goto / label
    • "goto文は、通常別のcaseにジャンプするときに使われる"
    • サンプルコードが政治
  • p53 空白文字と中括弧
    • コラムで空白文字と中括弧のスタイルについて
    • 趣味の問題であり、VSの設定で調整可能。
  • p55 四則演算演算子
    • "C#は、整数の割算をするとき、小学4年生ぐらいの子供が行うように割ります。" → つまり切り捨て
  • p67 クラスとオブジェクトについて
    • クラスは型であり、同時にカプセル化の手段である
    • "クラスとオブジェクトの違いは、犬という概念と足元に座っている特定の犬との間の違いになぞらえることができます。犬とは何なのかという定義を相手にして、これを取ってこいといいつけて遊ぶことはできません。遊び相手にできるのは特定のインスタンスです。"
    • "プログラミングに関する古い冗談に「電球を交換するために何人のオブジェクト指向プログラマが必要でしょうか?」、「ひとりも要りません。電球に、自身を交換するように指示すればよいのです」というものがあります(「ひとりも要りません。なぜなら、Microsoftが暗闇というものの基準そのものを変えてしまったからです」という答もあります)。"
  • p70 アクセス修飾子
    • public, private とかの表。アセンブリも一つの境界になる。
  • p71 アクセス修飾子は明示的に書くべき
    • "明示的に書いておくと、それは考えた結果の決定であるという事が伝わりますし、自己記述的にも出来ます。"
  • p73 VB6 の Dim, New と C# の new
    • VB6では Dim と New を同じ行で使うと性能が悪くなるらしい
  • p73 単純型の既定値
    • char の既定値は '\0'
  • p78 C#の「thisポインタ」
    • C#では「thisポインタ」は誤解のもとになるので、正しくは「this参照」を使う
    • "本書ではthis参照というように使い分けるようにしています。言い間違えた個所があれば、それぞれに25セントの罰金をチャリティに寄付しましょう。"
  • p80 staticメソッドはインスタンスから呼べない
    • Javaとは違う
  • p80 オブジェクトの名前 = ヒープ上の無名のインスタンスへの参照の値に付けられた名前
    • "本書において、オブジェクトの名前という表現をする場合、「ヒープ上の無名のインスタンスへの参照の値につけられた名前」を省略しているということを記憶の隅に置いておいてください。"
  • p85 デストラクタの動作
    • GCの動きを具体的に書いている
  • p87 using文
    • try - catch - finally よりも確実
  • p93 出力用の out, 参照渡し ref の例
    • Javaと同様、基本的に引数は「値渡し」。
    • out や ref を使うことで引数で値を返すことが出来る。
  • p99 set アクセサ
  • p102 readonly の代入ルール
    • コンストラクタ内では代入できる
  • p105 クラス階層の説明
    • 本文で陥りがちな悪い例を示して、コラムで自分で批判
    • →これで分かる人は面白いけど、分からない人は混乱しそう
  • p109 overrideキーワード
    • オーバーライドするには override って付ける必要がある
  • p111 既定コンストラクタ自動生成
  • p113 new virtual キーワード
    • new virtual を使うと、基本クラスが同名の派生クラスのメソッドを呼ばないように出来る
    • 規模が大きくなってメソッド名がぶつかる事故が起きて、意図せず基本クラスの動作を破壊することを防ぐらしい。
    • →うーん。余計な迷路を増やしただけにも見えるし、ちょっと気持ち悪い。
  • p122 ボックス化とボックス化解除
    • JavaのAutoboxingのように似た挙動をする違う値に変換されるのではなくて、単にObject型で包まれる。
    • 明示的にボックス化解除が必要。解除の際に null や型が違う場合に備えて try が必要。
    • JavaのAutoboxingは最悪だと思っているので、C#のボックス化はまだまし。
  • p123 C#入れ子クラス
    • JavaインスタンスにひもづいたインナークラスはC#にはない。あるのは Java でいう static なインナークラスのみ。
  • p127 比較演算子オーバーライド
    • C++では対になる演算子は<か=を用意するだけでよいが、C#では対になる演算子は両方定義する必要がある
  • p137 構造体は値渡し、参照にするにはボックス化が必要
    • →クラスと構造体の使い分けは難しそう
  • p140 構造体はnewしなくても使えるが、推奨されない
    • →何のためにあるのか?
  • p143 C#ではインタフェースに定数が書けない
  • p144 Mix In の話
    • 例のアイスクリーム屋の小話
  • p147 インタフェースでのアクセサ
    • publicしかありえないので、アクセス修飾子を書くとコンパイルエラー
  • p159 as演算子。isでチェックしてキャストする
    • →cast必要なときは便利そう
  • p161 抽象クラスかインタフェースか
    • Microsoft社内ではバージョン管理の都合からインタフェースよりも抽象クラスを好む人がいる
    • インタフェースはインタフェースと実装クラスの2つが必要。めんどう。抽象クラスであれば virtual 付けるだけでいい。
    • "なんということでしょう!"
  • p163 キャスト先の型によって動作が変わる!
    • インスタンスが同じでも、キャスト先のインタフェースの型によって動作を変えることが出来る
    • →サンプルコードは的確で分かりやすく、本文で説明されているメリットは理解できるが、それによるデメリットの方が大きくないのか?ちょっと気持ち悪い。
  • p166 インタフェース名を指定して実装するときはアクセス修飾子を付けられない
    • インタフェースはpublic以外ありえないから
  • p168 インタフェース名を指定して実装することで、インタフェースメンバの選択的公開が出来る、クラスのセマンティクスを守る
    • →熟考の上での選択だと思うけど、そんな複雑なことがどうしても必要なことがC#界隈にはあるのだろう。
  • p207 IEnumerableとyield
    • →見た目かなり違うけど、中身はRubyのyieldっぽい
  • p210 ジェネリクスの型の制約
    • →型の制約の書き方はどの言語も大変そう
  • p233 Dictionaryのキーをオブジェクトにするならキーのオブジェクトを変更してはいけない!
    • オブジェクトの中身を変更するとGetHashCodeが変わるので、オブジェクトをハッシュのキーにして変更すると探せなくなる
    • →ついやってしまいそう。こわい。
  • p236 stringとStringは等価
    • stringの内容を変更すると新しいオブジェクトの参照が帰る
  • p237 逐語的文字列リテラル
    • 基本的にエスケープされないが、ダブルクオートはエスケープする必要がある
    • JavaEmacs Lispにも欲しい
  • p242 case ignore な比較
    • "ここでは、1行を短くすることで結果の出力が書籍のページにきちんと収まるように、WriteLine()を2回呼出しています。" ??
  • p244 string の == はオーバーライドされているので中身で比較される
    • Javaもそうだったらよかった
  • p249 split の params キーワードの例
    • 可変長引数
  • p263 例外について
    • バグとエラーと例外の区別をつけよう
    • →いい話
  • p267 すべての例外をキャッチする書き方
  • p274 finally ブロックの制限
    • return, break などのジャンプを使うとエラー
  • p311 event キーワード
  • p316 delegate の匿名メソッド
    • lambda
  • p318 マルチキャストデリゲートの明示的な実行
    • →ここまでくると、わざわざ言語でサポートする必要があったのか疑問
  • p321 デリゲートの非同期実行
    • →話は面白いけど、多分説明が分かりにくそう
  • p341 コラム 亀は続く
    • スチーブン・ホーキング氏の小話
    • "「あなたはなかなかよくできた子ね。しかし亀は亀の上にいるのですよ。その繰り返しです。」"
  • p367 ADO.NET
  • p397 UIデザイン
    • "筆者はUIを完璧にデザインできるプログラマはいないと考えます。"
  • p400 ASP.NET
    • IsPostBack でポストされたかどうかの判断
    • →うーん。昔だからしょうがないかも。
  • p444 アセンブリとセキュリティ境界
    • 2つのアセンブリにまたがって型を定義することはできない。型の参照は出来る。
  • p452 デフォルトではプライベートアセンブリ
    • DLL地獄の解決策
  • p480 マーシャリングの説明
    • 約1ページに渡って、マーシャリングとチャンネルについてスター・トレックで説明
    • "例えば、カーク船長が文明の発展に重大な影響を与えるようなことを伝達しようとするとき、最初のシンクはこれを拒絶します。"
    • Prime Directive の知識が前提!!!!
  • p497 RPCのサンプルコードのコメント
    • "「ただそこに立ち、待つばかりの者もまた主に使えし者である」(ミルトン)"
    • キリスト教の知識が前提。深い。
  • p526 訳者注:デッドロック
    • アメリカでは「deadlock」、ヨーロッパでは「deadly embrace」が多い。ただし、embraceは2つのプロセス間の場合のみに使う。
  • p553 シングルスレッドでブロックするサーバーソケットのサンプルコードについて
    • "電話を目の前にして、鳴り出すのをいつまでも待っているような状態です。このモデルは1週間に2接続程度のサーバーであれば問題ないでしょうが、実際のアプリケーションとしてはほとんど使い物になりません。"
  • p612 fixed キーワード
    • fixedを使うとGCによって変更されないメモリアドレスのポインタを取得できる


この本はサイ本や詳説正規表現と並んでとても楽しかったです。

C/C++の方面から見るとそんなに不思議ではないけど、Java側から見ると落とし穴が多いと思います。Javaと字面は似てるけど、全く同じのつもりで業務でコード書いてる人(SE PGとかでよく見る)は気を付けた方が良いと思いました。(Lispに比べたら大した違いではないけど。。。)