本のタイトルにもなっているイディオム。
そもそもイディオムって何だろうと思っていたが、これはコーディングレベルでよく利用される汎用的なコードのこと。
なので、このイディオムを覚えれば、品質もよく、正しいコードを書けることに繋がりそう。特に自分が書いているコードって、思い通りには動くけど、プログラム上級者の人から見たら、どう思われるかいつも心配なので。。
初期化に関するイディオム
変数の宣言と初期化は同時に行うこと。
var age = 25;
配列とリストの初期化
初期化構文を使おう。初期化構文を使うと、要素の入れ替えや追加が楽になるから。
// 配列 var langs = new string[] { "C#", "VB", "C++", }; // リスト var nums = new List<int> { 10, 20, 30, 40, };
Dictionaryの初期化
こちらも同じく初期化構文を使おう。
// Dictionary var dict = new Dictionary<string, string>() { {"ja", "日本語" }, {"en", "英語" }, {"es", "スペイン語" }, {"de", "ドイツ語" }, };
オブジェクトの初期化
こちらも同じく初期化構文を使用する。オブジェクト生成とプロパティの初期化が同時に行える。
var person = new Person { Name = "山田太郎", Birthday = new DateTime(1995, 11, 23), };
初期化構文の特徴として、「要素の入れ替えや追加が容易になる」、「可読性が高まる」といった特徴がある。
判定のイディオム
単純な比較。
// 年齢が10才以下かという人の思考に基づく考え方 if (age <= 10)
数値が範囲内にあるかどうか。
// 数値を直線上に並べた比較 if(MinValue <= num && num <= MaxValue)
if文の中でのreturn文の使い方。
このように記載すれば、可読性が高まる。
// ふるいにかけて残ったものだけ処理する if (filePath == null) return; if (GetOption() == Option.Skip) return; // 実行したい処理
繰り返しのイディオム
ループ処理の考え方は、LINQ > foreach > forの順番で適用を考える。
なお、List
var nums = new List<int> { 1, 2, 3, 4, 5, }; // 12345と出力される nums.ForEach(n => Console.Write("{0}", n));
条件演算子、null合体演算子によるイディオム
条件演算子
// trueなら1、falseなら0を返却 var num = list.Contains(key) ? 1 : 0;
null合体演算子
// GetMessageがNULLを返却したら、DefaultMessageの値を変数messageにつめる
var message = GetMessage(code) ?? DefaultMessage();
null条件演算子
// sale変数がnullのとき、Productプロパティにアクセスせずにnullを返却する。 // NullPointerExceptionが発生しない return sale?.Product;
プロパティに関するイディオム
まずは、プロパティの初期化。コンストラクタに初期化処理を書かなくていい。
Javaで慣れている分、プロパティにまだまだ慣れないが。。
// プロパティの初期化 public int MinimumLength { get; set; } = 6;
次が、値を変更できない読み取り専用のプロパティの定義方法。
こう定義すると、外のクラスから値の変更はできなくなる。
public int MinimumLength { get; private set; }
メソッドに関するイディオム
可変長引数。引数の数を限定したくない場合に使用する。
Javaでいうオーバーロードするところを、引数の数の違いだけなら、この書き方で吸収できるというもの。
// 定義 public void WriteInt(params int[] args) { foreach(var db in args) { Console.WriteLine(db); } } // 実際の呼び出し方 pp.WriteInt(1, 2, 3, 4, 5);
次にオプション引数。引数を省略した際の初期値を、それぞれ設定できるというもの。
// 定義 public void DoSomething(int num, string message = "失敗しました", int retryCount = 3) { Console.WriteLine("{0},{1},{2}",num, message, retryCount); } // 実際の呼び出し方 pp.DoSomething(100); pp.DoSomething(100, "エラーです"); pp.DoSomething(100, "エラーです", 5);
その他のイディオム
ファイルパスの指定には、先頭に@を付加した逐次的リテラル文字列を使用する。
そうすると、¥記号がエスケープ文字として認識されなく、ファイルパスがそのまま記述可能。
var path = @"C:¥Example¥Greeting.txt";
2つの要素を入れ替える。
var temp = a; a = b; b = temp;
文字列を数値に変換する。
TryParseメソッドを使用する。エラーハンドリングも行ってくれて、便利!
int height; if (int.TryParse(str, out height)) { // 変換に成功したときの処理 } else { // 変換に失敗したときの処理 }