前回のBlog Post - Developers Summit Demo Script – Part Iでは、プロジェクトのセットアップとC# 3.0の新しい構文のひとつ‘ローカル変数の型推論’を紹介しました。今回は、前回のコードをもとに、更に変更をくわえていきます。 今回、紹介する機能はオブジェクト イニシャライザです。
まず、前回使用したプロジェクトをVS2008で開いてください。 つぎに、default.aspx.csをエディタで開きGetProductList()メソッドにカーソルを移動してください。
C#2.0 & 昨日までの変更
var productList = new List<Product>();
productList.Add(new Product(1, 1, "Chai", 18.0000M));
productList.Add(new Product(2, 1, "Chang", 19.0000M));
をC# 3.0 のオブジェクト イニシャライザ構文を使って、書き換えると
var productList = new List<Product> {
new Product { ProductID = 1, CategoryID = 1, ProductName = "Chai" , UnitPrice=18.0000M },
new Product { ProductID = 2, CategoryID = 1, ProductName = "Chang" , UnitPrice=19.0000M },
…
//残りのコードはここからダウンロードしてGetProductList()メソッドを置き換えてください
Product(1, 1, "Chai", 18.0000M) が new Product { ProductID = 1, CategoryID = 1, …} に変わりました。
まず、詳しくコンパイラの視点から見てみます。コンパイル時にコンパイラがチェックできるのは型の整合性だけです。 例えば、C#2.0で
Product(1, 1, "Chai", 18.0000M) を Product("1", 1, "Chai", 18.0000M)
と書いた場合コンパイラは string->int の型変換ができませんので、Syntaxエラーとなります。
次に、Productクラスのコンストラクタを見てください。
public Product(int productID, int categoryID, string productName, decimal unitPrice){ ... }
当たり前のことですが、引数の順番は重要で、引数が意味を持ち、その順番を間違えると実行時のエラーつまりBugの原因になります。 例えば、
new Product(2, 1, "Chang", 19.0000M) と書くところを productID と catetoryID を間違って
new Product(1, 2, "Chang", 19.0000M) としたとします。
このコードはSyntax的には正しいですのでコンパイルも問題なく通り、実行することができます。 しかし、実行時の結果は予期しなかったものになります。 C# 3.0のオブジェクト イニシャライザ構文を使っていただくことにより、もちろん同様の間違えをすることは可能ですが、どのメンバを初期化しているのかを明示できる、よってエラーの原因を減らすことにつながります。
new Product { ProductID = 1, CategoryID = 1, ProductName = "Chai" , UnitPrice=18.0000M },
new Product { ProductID = 2, CategoryID = 1, ProductName = "Chang" , UnitPrice=19.0000M },
同じようにDebugまたは保守時のストを削減できることができると思います。
まとめとして、コードを書いた人が何をやろうとしているのかがより分かりやすくなりました。 これは、C# 3.0 の開発コンセプトのいかに簡潔に宣言的にコードを書けるかに沿っています。 コンストラクタの引数の順位も気にせずに明示的にメンバの名前でオブジェクトを初期化をできますので、Potential Bugを開発時に食い止めることができるようになります。
次回は自動実装 プロパティの予定です。
注: 今回のコードの修正のあとコンパイルするとエラーがでます。エラーを回避するにはProductクラスにDefaultコンストラクタを追加してください。