目次
Part 1 [準備編]C#プログラミングのイディオム/定石&パターン
Chapter 1 オブジェクト指向プログラミングの基礎
- 1.1 クラス
- 1.1.1 クラスを定義する
- 1.1.2 クラスのインスタンスを生成する
- 1.1.3 オブジェクトを利用する
- 1.1.4 インスタンスは複数作れる
- 1.2 構造体
- 1.3 値型と参照型
- 1.3.1 値型の動き
- 1.3.2 参照型の動き
- 1.3.3 なぜ値型と参照型が必要なのか
- 1.4 静的メンバーと静的クラス
- 1.4.1 静的プロパティと静的メソッド
- 1.4.2 静的クラス
- 1.5 名前空間
- 1.5.1 名前空間とは
- 1.5.2 usingディレクティブ
- 1.5.3 名前空間の定義
- 1.6 継承
- 1.6.1 継承とは?
- 1.6.2 is-a関係
- 1.7 null許容参照型
- 1.7.1 nullとは何か
- 1.7.2 null許容型 Nullable
- 1.7.3 null許容参照型
- Chapter 1の演習問題
Chapter 2 C#でプログラムを書いてみよう
- 2.1 距離換算プログラム
- 2.1.1 最初のバージョン
- 2.1.2 計算ロジックをメソッドとして独立させる
- 2.1.3 プログラムに機能を追加する
- 2.1.4 メソッドとして独立させる
- 2.1.5 クラスとして分離する
- 2.1.6 クラスを利用する
- 2.1.7 静的メソッドに変更する
- 2.1.8 静的クラスにする
- 2.1.9 定数を定義する
- 2.2 売り上げ集計プログラム
- 2.2.1 Saleクラスを定義する
- 2.2.2 CSVファイルを読み込む
- 2.2.3 店舗別売り上げを求める
- 2.2.4 集計結果を出力する
- 2.2.5 初版の完成
- 2.2.6 メソッドの移動
- 2.2.7 新たなコンストラクターの追加
- 2.2.8 クラスをインターフェースに置き換える
- 2.2.9 varによる暗黙の型指定を使う
- 2.2.10 完成したソースコード
- Chapter 2の演習問題
Chapter 3 ラムダ式とLINQの基礎
- 3.1 ラムダ式以前
- 3.1.1 メソッドを引数に渡したい
- 3.1.2 デリゲートによる実現
- 3.1.3 匿名メソッドの利用
- 3.2 ラムダ式
- 3.2.1 ラムダ式とは?
- 3.2.2 ラムダ式を使った例
- 3.3 List<T>クラスとラムダ式の組み合わせ
- 3.3.1 Existsメソッド
- 3.3.2 Findメソッド
- 3.3.3 FindIndexメソッド
- 3.3.4 FindAllメソッド
- 3.3.5 RemoveAllメソッド
- 3.3.6 ForEachメソッド
- 3.3.7 ConvertAllメソッド
- 3.4 LINQ to Objectsの基礎
- 3.4.1 LINQ to Objectsの簡単な例
- 3.4.2 クエリ演算子
- 3.4.3 シーケンス
- 3.4.4 遅延実行
- Chapter 3の演習問題
Part 2 [基礎編]C#プログラミングのイディオム/定石&パターン
Chapter 4 基本イディオム
- 4.1 初期化に関するイディオム
- 4.1.1 変数の初期化
- 4.1.2 配列とリストの初期化
- 4.1.3 ディクショナリの初期化
- 4.1.4 オブジェクトの初期化
- 4.2 判定と分岐に関するイディオム
- 4.2.1 単純な比較
- 4.2.2 数値がある範囲内にあるか調べる
- 4.2.3 多分岐処理
- 4.2.4 条件により代入する値を変更する
- 4.2.5 bool値の値が真かどうかを判断する
- 4.2.6 bool値を返す
- 4.2.7 ふるいにかけて残ったものだけ処理をする
- 4.3 繰り返しのイディオム
- 4.3.1 指定した回数だけ繰り返す
- 4.3.2 コレクションの要素をすべて取り出す
- 4.3.3 List<T>のすべての要素に対して処理をする
- 4.3.4 最低1回は繰り返す
- 4.3.5 ループの途中で処理をやめたい
- 4.4 nullに関するイディオム
- 4.4.1 nullかどうかの判定
- 4.4.2 null合体演算子
- 4.4.3 null合体代入演算子
- 4.4.4 null条件演算子
- 4.5 列挙型に関するイディオム
- 4.5.1 列挙型の基本的な使い方
- 4.5.2 ビットフラグとして利用する
- 4.6 その他のイディオム
- 4.6.1 1を加える場合はインクリメント演算子++を使う
- 4.6.2 2つの要素を入れ替える
- 4.6.3 ファイルパスには逐語的リテラル文字列を使う
- 4.6.4 文字列を数値に変換する
- 4.6.5 参照型のキャスト
- 4.6.6 例外を再スローする
- 4.6.7 usingを使ったリソースの破棄
- Chapter 4の演習問題
Chapter 5 クラスに関するイディオム
- 5.1 プロパティに関するイディオム
- 5.1.1 プロパティの初期化
- 5.1.2 読み取り専用プロパティ
- 5.1.3 getオンリープロパティ
- 5.1.4 参照型の読み取り専用プロパティ
- 5.2 メソッドに関するイディオム
- 5.2.1 式形式のメソッド
- 5.2.2 可変長引数
- 5.2.3 オーバーロードよりオプション引数を使う
- 5.3 コンストラクターに関するイディオム
- 5.3.1 コンストラクターでフィールドを初期化する
- 5.3.2 複数のコンストラクターを定義する
- 5.4 さらに進んだクラスの定義
- 5.4.1 requiredプロパティ
- 5.4.2 プライマリコンストラクター
- 5.4.3 レコード型
- Chapter 5の演習問題
Chapter 6 文字列の操作
- 6.1 文字列の比較
- 6.1.1 文字列どうしを比較する
- 6.1.2 大文字/小文字の区別なく比較する
- 6.1.3 ひらがな/カタカナの区別なく比較する
- 6.1.4 全角/半角の区別なく比較する
- 6.2 文字列の判定
- 6.2.1 nullあるいは空文字列かを調べる
- 6.2.2 指定した部分文字列で始まっているか調べる
- 6.2.3 指定した部分文字列が含まれているか調べる
- 6.2.4 条件を満たしている文字が含まれているか調べる
- 6.2.5 すべての文字がある条件を満たしているか調べる
- 6.3 文字列の検索と抽出
- 6.3.1 部分文字列を検索し,その位置を求める
- 6.3.2 文字列の一部を取り出す
- 6.4 文字列の変換
- 6.4.1 文字列の前後の空白を取り除く
- 6.4.2 指定した位置から任意の数の文字を削除する
- 6.4.3 文字列に別の文字列を挿入する
- 6.4.4 文字列の一部を別の文字列で置き換える
- 6.4.5 小文字を大文字に変換する/大文字を小文字に変換する
- 6.5 文字列の連結と分割
- 6.5.1 2つの文字列を連結する
- 6.5.2 文字列を末尾に追加する
- 6.5.3 指定した区切り文字で文字列配列を連結する
- 6.5.4 文字列を指定した文字で分割する
- 6.5.5 StringBuilderを使った文字列の連結
- 6.6 その他の文字列操作
- 6.6.1 文字列から文字を1つずつ取り出す
- 6.6.2 文字配列から文字列を生成する
- 6.6.3 数値を文字列に変換する
- 6.6.4 指定した書式で文字列を整形する
- Chapter 6の演習問題
Chapter 7 配列とList<T>の操作
- 7.1 本章で共通に使用するコード
- 7.2 要素の設定
- 7.2.1 配列あるいはList<T>を同じ値で埋める
- 7.2.2 配列あるいはList<T>に連続した値を設定する
- 7.3 コレクションの集計
- 7.3.1 平均値を求める
- 7.3.2 最小値,最大値を得る
- 7.3.3 条件に一致する要素をカウントする
- 7.4 コレクションの判定
- 7.4.1 条件に一致する要素があるか調べる
- 7.4.2 すべての要素が条件を満たしているか調べる
- 7.4.3 2つのコレクションが等しいか調べる
- 7.5 単一の要素の取得
- 7.5.1 条件に一致する最初/最後の要素を取得する
- 7.5.2 条件に一致する最初/最後のインデックスを求める
- 7.6 複数の要素の取得
- 7.6.1 条件を満たす要素をn個取り出す
- 7.6.2 条件を満たしている間だけ要素を取り出す
- 7.6.3 条件を満たしている間は要素を読み飛ばす
- 7.7 その他の処理(変換,ソート,連結など)
- 7.7.1 コレクションから別のコレクションを生成する
- 7.7.2 重複を排除する
- 7.7.3 コレクションを並べ替える
- 7.7.4 2つのコレクションを連結する
- Chapter 7の演習問題
Chapter 8 ディクショナリの操作
- 8.1 Dictionary<TKey, TValue>の基本操作
- 8.1.1 ディクショナリの初期化
- 8.1.2 ユーザー定義型のオブジェクトを値に格納する
- 8.1.3 ディクショナリに要素を追加する
- 8.1.4 ディクショナリから要素を取り出す
- 8.1.5 ディクショナリから要素を削除する
- 8.1.6 ディクショナリからすべての要素を取り出す
- 8.2 ディクショナリの応用
- 8.2.1 ディクショナリに変換する
- 8.2.2 ディクショナリから別のディクショナリを作成する
- 8.2.3 カスタムクラスをキーにする
- 8.2.4 HashSet<T>でキーのみを格納する
- 8.2.5 キーの重複を許す
- 8.3 ディクショナリを使ったサンプルプログラム
- 8.3.1 Abbreviationsクラス
- 8.3.2 Abbreviationsを利用する
- Chapter 8の演習問題
Chapter 9 日付,時刻の操作
- 9.1 DateTime構造体
- 9.1.1 DateTimeオブジェクトの生成
- 9.1.2 DateTimeのプロパティ
- 9.1.3 指定した日付の曜日を求める
- 9.1.4 閏年か判定する
- 9.1.5 日付形式の文字列をDateTimeオブジェクトに変換する
- 9.2 日時のフォーマット
- 9.2.1 日時を文字列に変換する
- 9.2.2 日付を和暦で表示する
- 9.2.3 指定した日付の元号を得る
- 9.2.4 指定した日付の曜日の文字列を得る
- 9.3 DateTimeの比較
- 9.3.1 日時を比較する
- 9.3.2 日付のみを比較する
- 9.4 日時の計算(基礎)
- 9.4.1 指定した時分秒後を求める
- 9.4.2 n日後,n日前の日付を求める
- 9.4.3 n年後,nヵ月後を求める
- 9.4.4 2つの日時の差を求める
- 9.4.5 2つの日付の日数差を求める
- 9.4.6 月末日を求める
- 9.4.7 1月1日からの通算日を求める
- 9.5 日時の計算(応用)
- 9.5.1 次の指定曜日を求める
- 9.5.2 年齢を求める
- 9.5.3 指定した日が第何週か求める
- 9.5.4 指定した月の第n回めのX曜日の日付を求める
- Chapter 9の演習問題
Part 3 [実践編]C#プログラミングのイディオム/定石&パターン
Chapter 10 ファイルの操作
- 10.1 テキストファイルの入力
- 10.1.1 テキストファイルを1行ずつ読み込む
- 10.1.2 テキストファイルを一気に読み込む
- 10.1.3 テキストファイルをIEnumerable<string>として扱う
- 10.2 テキストファイルへの出力
- 10.2.1 テキストファイルに1行ずつ文字列を出力する
- 10.2.2 既存テキストファイルの末尾に行を追加する
- 10.2.3 文字列の配列を一気にファイルに出力する
- 10.2.4 既存テキストファイルの先頭に行を挿入する
- 10.3 ファイルの操作
- 10.3.1 ファイルの有無を調べる
- 10.3.2 ファイルを削除する
- 10.3.3 ファイルをコピーする
- 10.3.4 ファイルを移動する
- 10.3.5 ファイル名を変更する
- 10.3.6 ファイルの最終更新日時/作成日時の取得/設定
- 10.3.7 ファイルのサイズを得る
- 10.3.8 FileとFileInfo,どちらを使うべきか?
- 10.4 ディレクトリの操作
- 10.4.1 ディレクトリの有無を調べる
- 10.4.2 ディレクトリを作成する
- 10.4.3 ディレクトリを削除する
- 10.4.4 ディレクトリを移動する
- 10.4.5 ディレクトリ名を変更する
- 10.4.6 指定フォルダーにあるファイルの一覧を一度に取得する
- 10.4.7 指定フォルダーにあるディレクトリの一覧を一度に取得する
- 10.4.8 ディレクトリとファイルの一覧を一緒に取得する
- 10.4.9 ディレクトリとファイルの更新日時を変更する
- 10.5 パス名の操作
- 10.5.1 パス名を構成要素に分割する
- 10.5.2 相対パスから絶対パスを得る
- 10.5.3 パスを組み立てる
- 10.6 その他のファイル操作
- 10.6.1 一時ファイルを作成する
- 10.6.2 特殊フォルダーのパスを得る
- Chapter 10の演習問題
Chapter 11 正規表現を使った高度な文字列処理
- 11.1 正規表現とは?
- 11.2 文字列の判定
- 11.2.1 指定したパターンに一致した部分文字列があるか判定する
- 11.2.2 指定したパターンで文字列が始まっているか判定する
- 11.2.3 指定したパターンで文字列が終わっているか判定する
- 11.2.4 指定したパターンに完全に一致しているか判定する
- 11.3 文字列の検索
- 11.3.1 最初の部分文字列を見つける
- 11.3.2 一致する文字列をすべて見つける
- 11.3.3 Matchesメソッドの結果にLINQを適用する
- 11.3.4 一致した部分文字列の一部だけを取り出す
- 11.4 文字列の置換と分割
- 11.4.1 Regex.Replaceメソッドを使った簡単な置換処理
- 11.4.2 グループ化を使った置換
- 11.4.3 Regex.Splitメソッドによる分割
- 11.5 さらに高度な正規表現
- 11.5.1 量指定子
- 11.5.2 最長一致と最短一致
- 11.5.3 前方参照構成体
- Chapter 11の演習問題
Chapter 12 シリアル化,逆シリアル化
- 12.1 JSONデータのシリアル化/逆シリアル化の基礎
- 12.1.1 JSONシリアル化
- 12.1.2 JSONデータの逆シリアル化
- 12.2 JsonSerializerクラスの既定の動作を変更する
- 12.2.1 プロパティを無視する
- 12.2.2 JSONプロパティのキー名をカスタマイズする
- 12.2.3 JSONプロパティのキー値を明示する
- 12.2.4 数値の取り扱い方法を変更する
- 12.3 XMLシリアル化
- 12.3.1 XmlSerializerを使ったシリアル化
- 12.3.2 XmlSerializerを使った逆シリアル化
- 12.3.3 XmlIgnore属性でシリアル化の対象から除外する
- 12.3.4 属性で要素名(タグ名)を既定値から変更する
- 12.3.5 プロパティが配列の場合のシリアル化
- 12.3.6 XmlSerializerを使ったコレクションのシリアル化
- 12.3.7 XmlSerializerを使ったコレクションの逆シリアル化
- Chapter 12の演習問題
Chapter 13 LINQを使いこなす
- 13.1 本章で利用する書籍データなどについて
- 13.2 入力ソースが1つの場合のLINQ
- 13.2.1 ある条件の中の最大値を求める
- 13.2.2 最小値の要素を1つだけ取り出す
- 13.2.3 平均値以上の要素をすべて取り出す
- 13.2.4 重複を取り除く
- 13.2.5 複数のキーで並べ替える
- 13.2.6 複数の要素のいずれかに該当するオブジェクトを取り出す
- 13.2.7 GroupByメソッドでグルーピングする
- 13.2.8 ToLookupメソッドでグルーピングする
- 13.3 入力ソースが複数の場合のLINQ
- 13.3.1 2つのシーケンスを結合する
- 13.3.2 2つのシーケンスをグルーピングして結合する
- Chapter 13の演習問題
Chapter 14 非同期/並列プログラミング
- 14.1 非同期処理,並列処理の必要性
- 14.2 async/await以前の非同期プログラミング
- 14.2.1 Threadを使った非同期処理
- 14.2.2 BackgroundWorkerクラスを使った非同期処理
- 14.2.3 Taskクラスを使った非同期処理
- 14.3 async/awaitを使った非同期プログラミング
- 14.3.1 イベントハンドラーを非同期にする
- 14.3.2 非同期メソッドを定義する
- 14.3.3 async/awaitの実例 非同期IO処理
- 14.4 HttpClientを使った非同期処理 async/awaitの応用例
- 14.4.1 HttpClientの簡単な例
- 14.4.2 HttpClientの応用
- 14.5 並列処理プログラミング
- 14.5.1 PLINQによる並列処理
- 14.5.2 Taskクラスを使った並列処理
- 14.5.3 HttpClientでの並列処理
- Chapter 14の演習問題
Part 4 [ステップアップ編]C#プログラミングのイディオム/定石&パターン
Chapter 15 実践オブジェクト指向プログラミング
- 15.1 ポリモーフィズムの基礎
- 15.1.1 継承を使ったポリモーフィズム
- 15.1.2 インターフェースを使ったポリモーフィズム
- 15.2 Template Methodパターン
- 15.2.1 ライブラリとフレームワーク
- 15.2.2 テキストファイルを処理するフレームワーク
- 15.2.3 テキストファイル処理のフレームワークの実装
- 15.2.4 フレームワークの利用(アプリケーションの作成)
- 15.2.5 プログラムを実行する
- 15.3 Strategyパターン
- 15.3.1 距離換算プログラムを再考する
- 15.3.2 Converterに共通するメソッド,プロパティを定義する
- 15.3.3 Converterの具象クラスを定義する
- 15.3.4 距離の単位変換を担当するクラスを定義する
- 15.3.5 オブジェクト生成を一元管理する
- 15.3.6 プログラムを完成させる
- 15.4 依存性の注入パターン
- 15.4.1 オブジェクトコンポジションでLineCounterを書き換える
- 15.4.2 依存性の注入(DI)を導入する
- 15.4.3 WordCounterプログラムを作成する
- Chapter 15の演習問題
Chapter 16 C#を使いこなす
- 16.1 インデクサー
- 16.1.1 インデクサーとは
- 16.2 ジェネリックス
- 16.2.1 ジェネリッククラスの基本
- 16.2.2 型パラメーターの制約
- 16.2.3 ジェネリックメソッド
- 16.2.4 defaultキーワード
- 16.3 反復子
- 16.3.1 反復子とは
- 16.3.2 yield breakステートメント
- 16.3.3 クラスを列挙可能にする
- 16.4 拡張メソッド
- 16.4.1 拡張メソッドとは
- 16.4.2 拡張メソッドの定義
- 16.4.3 ジェネリックな拡張メソッド
- 16.5 属性
- 16.5.1 属性の利用
- 16.5.2 カスタム属性の作成
- 16.6 タプル
- 16.6.1 タプルの基本的な使い方
- 16.6.2 タプルの各フィールドに名前を指定する
- 16.6.3 タプルの比較
- 16.6.4 Deconstructメソッドによる分解
- 16.7 パターンマッチング
- 16.7.1 nullチェック
- 16.7.2 宣言パターン 型のテスト
- 16.7.3 論理パターン
- 16.7.4 リレーショナルパターン
- 16.7.5 リストパターン
- 16.7.6 位置指定パターン
- 16.7.7 プロパティパターン
Chapter 17 スタイル,ネーミング,コメント
- 17.1 スタイルに関する指針
- 17.1.1 構造をインデントに反映させる
- 17.1.2 括弧を使ってわかりやすくする
- 17.1.3 1行に詰め込み過ぎない
- 17.2 ネーミングに関する指針
- 17.2.1 Pascal形式とCamel形式を適切に使う
- 17.2.2 それが何を表すものか説明する名前を付ける
- 17.2.3 正しいつづりを使う
- 17.2.4 ローカル変数の省略形は誤解のない範囲で利用する
- 17.2.5 ローカル変数の1文字変数は用途を絞る
- 17.2.6 変数名/プロパティ名は名詞が良い
- 17.2.7 bool型であることがわかる名前にする
- 17.2.8 メソッド名には動詞を割り当てる
- 17.2.9 好ましくない名前
- 17.3 コメントに関する指針
- 17.3.1 コメントにはわかりきったことは書かない
- 17.3.2 クラスやメソッドのコメントには概要を書く
- 17.3.3 コードから読み取れない情報をコメントに書く
- 17.3.4 ダメなコードにコメントを書くよりコードを書き換える
- 17.3.5 コメントは必要最低限にする
- 17.3.6 コードをコメントアウトしたままにしない
- 17.3.7 見た目を重視した形式のコメントは書かない
Chapter 18 良いコードを書くための指針
- 18.1 変数に関する指針
- 18.1.1 変数のスコープは狭くする
- 18.1.2 マジックナンバーは使わない
- 18.1.3 変数を使い回してはいけない
- 18.1.4 1つの変数に複数の値を詰め込まない
- 18.1.5 変数の宣言はできるだけ遅らせる
- 18.1.6 変数の数は少なくする
- 18.2 メソッドに関する指針
- 18.2.1 ネストは浅くする
- 18.2.2 return文を1つにしようと頑張ってはいけない
- 18.2.3 実行結果の状態をint型で返してはいけない
- 18.2.4 メソッドは単機能にする
- 18.2.5 メソッドは短くする
- 18.2.6 何でもできる万能メソッドは作らない
- 18.2.7 メソッドの引数はできるだけ少なくする
- 18.2.8 引数にrefキーワードを付けたメソッドは定義しない
- 18.2.9 引数にoutキーワードを付けたメソッドは可能な限り定義しない
- 18.3 クラスに関する指針
- 18.3.1 フィールドは非公開にする
- 18.3.2 書き込み専用プロパティは定義しない
- 18.3.3 連続して参照すると異なる値が返るプロパティを定義してはいけない
- 18.3.4 コストのかかる処理はプロパティではなくメソッドにする
- 18.3.5 オブジェクトが保持している別のオブジェクトを外にさらしてはいけない
- 18.3.6 基底クラスをユーティリティメソッドの入れ物にしてはいけない
- 18.3.7 プロパティを引数代わりにしてはいけない
- 18.3.8 巨大なクラスは作成しない
- 18.3.9 new修飾子を使って継承元のメソッドを置き換えてはいけない
- 18.4 例外処理に関する指針
- 18.4.1 例外をひねり潰してはいけない
- 18.4.2 例外をthrowする際,InnerExceptionを破棄してはいけない
- 18.5 その他の好ましくないプログラミング
- 18.5.1 constの誤用
- 18.5.2 重複したコード
- 18.5.3 Obsolete属性の付いたクラス,メソッドを使い続ける
- 18.5.4 不要なコードをそのまま残し続ける
Appendix その他のプログラミングの定石
- A.1 プロセスの起動
- A.1.1 プログラムの起動
- A.1.2 プロセスの終了を待つ
- A.1.3 ProcessStartInfoクラスを用いて細かな制御をする
- A.2 バージョン情報の取得
- A.2.1 バージョン情報の設定
- A.2.2 バージョン情報の取得
- A.2.3 バージョン文字列を取得する
- A.3 アプリケーション構成ファイルの取得
- A.3.1 アプリケーション構成プロバイダーの設定
- A.3.2 appSettings情報の取得
- A.3.3 独自クラスのオブジェクトにバインドする
- A.4 ZIPアーカイブファイルの操作
- A.4.1 アーカイブからすべてのファイルを抽出する
- A.4.2 アーカイブに格納されているファイルの一覧を得る
- A.4.3 アーカイブから任意のファイルを抽出する
- A.4.4 指定ディレクトリ内のファイルをアーカイブする
- A.5 協定世界時とタイムゾーン
- A.5.1 現地時刻とそれに対応するUTCを得る
- A.5.2 文字列からDateTimeOffsetに変換する
- A.5.3 指定した地域のタイムゾーンを得る
- A.5.4 タイムゾーンの一覧を得る
- A.5.5 指定した地域の現在時刻を得る
- A.5.6 日本時間から指定した現地時間に変換する
- A.5.7 A地域の時刻をB地域の時刻に変換する