Effective C# 第1章

買ったので読む。 www.amazon.co.jp

個人的な読書ノートであり、自分の解釈が誤っていたり要点がずれてる可能性があります。内容が気になる人は自分で読んでください。

C#言語イディオム

1. ローカル変数の型をなるべく暗黙的に指定すること

  • 基本的に var を使う。数値型の場合は型を明記することを推奨する。
  • varはコンパイル時にコンパイラが適切な型を選んでくれる。
  • 三者がコードを読んだ際にローカル変数の型がすぐにわからない場合は明記するべき。

2. constよりもreadonly

  • constのほうがわずかにオーバーヘッドは少ないが、readonlyのほうが柔軟性が高い。
  • constは定数埋め込み。readonlyは動的に参照。
  • public定数の更新はインターフェースの更新である(バイナリ互換性を壊す)。使用箇所を再コンパイルしないと反映されない。
  • constじゃないと駄目なところ以外は使うべきではない。

3. キャストではなく is または as を使用する

  • 大前提として、型の変換は避けるべき。 どうしても変換しないといけないときは、is,asを用いて意図を明確にする。
  • キャスト演算は思わぬ動作をすることがある。
  • 一部コードでは値型と参照型に両対応するためキャストを使用している。(このため例外が出ることがある)
  • System.Obect 型はから任意の型へは変換演算子が定義されていないことを利用する。

4. string.Format を補完文字列に置き換える

  • 可読性高く文字列を生成できる。
  • 書式指定文字列(":F2"など)や、補完式(":{}")も使いなれる。
  • もちろんSQL文を作ったりするのには使わないこと。

5. カルチャ固有文字列よりFormattableStringを使う

  • FormattableString s = $"foo"; はFormattableString型になる。string.Formatに渡すformatとargumentを保持した変数になる。
  • あとはカルチャを指定してstring.Formatを実行する。
  • ローカライゼーションで非常に役立つ機能。

6. 文字列指定APIを使用しないこと

  • 型の安全性が失われる。
  • nameof()式を使うことでシンボル名を取得できるので活用しよう。

7. デリゲートを使用してコールバックを表現する

  • デリゲートはタイプセーフなコールバックを定義できるもの。
  • クラス間でデータをやり取りするが、インターフェースを使用するほど密に連携させたくない場合に最適な選択肢。積極的に使って良い。

  • マルチキャストデリゲートの注意点

    • 例外に対して安全ではない。途中で例外が出ると後ろは実行されない。
    • 返り値は最後に実行されたメソッドの返り値になる。

8. イベント呼び出し時にnull条件演算子を使用すること

Updated?.Invoke(this, counter)

簡素にかけるだけではなく、スレッドセーフなnullチェックになる。

9. ボックス化およびボックス化解除を最小限に抑える

  • 値型をインターフェース経由で操作する場合にもボックス化、ボックス化解除が行われる。
  • 値型をSystem.Objectの代わりに使用すると暗黙的に変換されやすいので避ける。(翻訳怪しい?)
struct Person {...}
var attendees = new List<Person>();
  • Listを操作するたびにコピーが発生してバグを埋め込みやすい。
  • JITコンパイラはPersonがボクシングされないようにListに特化したジェネリック型を生成する。

10. 親クラスの変更に応じる場合のみ new 演算子を使用すること

  • 親クラスの非virtualメンバを、小クラスでnewをつけると再定義できる。
  • これは静的に別のメソッドになっている。virtualメソッドは動的に結び付けられる。
  • 親クラスは必要最低限(小クラスで再定義してほしいメソッドのみ)にvirtualをつけること。
  • 小クラスは親クラスが名前を被せてきたときにのみnewを使ってもいいかもしれない。