![]() ![]() ![]() ![]() C# 3.0の新しい構文:デザインガイドラインこの記事のURLhttp://japan.internet.com/developer/20080513/26.html
著者:Peter Ritchie
海外internet.com発の記事
はじめにC# 3.0では、言語的にいくつかの構文が追加されています。この追加は、かなりの部分において、統合言語クエリ(LINQ)をサポートするために行われた変更と言ってよいでしょう。追加された機能としては、ラムダ式、拡張メソッド、匿名型、暗黙的に型付けされたローカル変数、自動プロパティ、オブジェクト初期化子などがあります(他にも多数の機能があります)。追加された構文の大部分は、ごく特定のニーズを満たすものであり、これによって既に確立されているコーディング手法やデザイン手法およびガイドラインの重要性が低下するようなことはありません。迷ったときは、新しい構文ではなく従来のガイドラインを優先してください。 MicrosoftのAnson Horton氏は、「The Evolution Of LINQ And Its Impact On The Design Of C#」という優れた記事の中で、LINQがC# 3.0のデザインにもたらす影響について論じるとともに、新しい言語機能を独特な観点から採り上げています。 ラムダ式ラムダ式はC# 2.0の匿名メソッドが進化したものと考えられます。ラムダメソッドは、関数型プログラミング(計算を数学関数の評価として扱い、ステートや変動データを避ける枠組み)をC#で採用しようとしたものです。ラムダ式はラムダ計算に基づいています。 使用時のヒント
拡張メソッドおそらく大いに賛否が分かれそうな追加構文の1つが拡張メソッドです。拡張メソッドを使用すると、どのクラスにも静的メソッドを「注入」(inject)することができます。拡張メソッドは基本的に、特定の型のインスタンスで動作する静的メソッドを作成するためのいわゆる構文糖(syntactic sugar)です。C# 3.0以前は、一般的なユーティリティメソッドを次のように書いていました。public static bool IsStringPlural(String text, CultureInfo cultureInfo) {/* ... */} String text = "languages"; Boolean isPlural = StringExtensions.IsStringPlural( text, new CultureInfo("en")); public static bool IsPlural(this String text, CultureInfo cultureInfo) {/* ... */} String text = "languages"; Boolean isPlural = text.IsPlural( new CultureInfo("en")); 拡張メソッドは通常の静的メソッドとまとめて扱われ、次のように使用できます。 String text = "languages"; Boolean isPlural = StringExtensions.IsPlural(text, new CultureInfo("en")); 拡張メソッドの主な難点は、名前解決の問題です。基本的にすべての拡張メソッドはグローバルで、名前も引数の数も同じメソッドは今のところ区別できません。そのため、拡張メソッドはもともとネームスペースの適切な運用を妨げる性質を持っており、現時点では、スコープを明確に区切る方法はありません。つまり、ファイルにusingステートメントを追加するだけで、コンパイルエラーが発生する可能性があります。 使用時のヒント
編集部注
この記事の初出は『CoDe Magazine』の2008年1月/2月号です。承諾を得て再掲しています。
匿名型匿名型を使用すると、クラス宣言を行わずにクラスをインスタンス化できます。言うまでもありませんが、このクラスには名前がないので、varキーワードの使用が必要になります。次に例を示します。var person = new { Name = "Peter", Age=4}; また、匿名型は不変(immutable)です。これはつまり、匿名型をインスタンス化するときにはフィールドではなく読み取り専用のプロパティを宣言するということです。このようなプロパティはgetのみを持ち、setはありません。 要するに、匿名型は実際にはきわめて一時的なデータのみに有用です。 使用時のヒント
暗黙的に型付けされたローカル変数賛否が分かれそうなもう1つの追加は、暗黙的に型付けされたローカル変数です。これをvarと呼ぶことにします。この呼び方についてはさておき(varとしておけば、他の型と混同する可能性は非常に低くなるでしょう)、varが導入された主な理由は、LINQクエリで返される型には匿名型が含まれることがあり、必ずしも人間が読み取りやすい名前になるとは限らないからです。LINQステートメントから返される型は、きわめて複雑になることもあります。匿名型を扱わない場合は、結果の型を推定して、宣言において手動で型付けできる可能性もあります。しかし、たいていの場合、データベースクエリは非常に可変性が高いので、変更のたびに型を再推定する必要があります。 LINQステートメントでの使用を別にしても、varを使用するとソースコードの読みやすさが低下し、検索が難しくなる傾向があります。たとえばMyClassというクラスを宣言し、このクラスをインスタンス化するときに毎回varを使用していると、var変数への代入式の右辺でクラス名を使用していない限り、コード内で「MyClass」を検索して使用箇所を特定することができなくなります。 C#では、大半の式で予測どおりの型が生成されますが、そうでないこともあります。二項演算と整数型がその好例です。整数の二項演算では、一方の項が符号あり(signed)でもう一方の項が符号なし(unsigned)の演算はサポートされません。次のコードではエラーが発生します。 uint unsignedNumber = 42; int signedNumber = 10; int result = unsignedNumber * signedNumber; int result = (long)unsignedNumber * signedNumber 結果の型を指定するのにint型の代わりにvarを使用すると、エラーは解決します。 var result = unsignedNumber * signedNumber; もう1つ、メソッドの戻り値の型に関するちょっとした例を紹介しましょう。あるメソッドの結果にvarを使用すると、その変数を使用するコードは、メソッドの実装に関連付けられることになります。後でそのメソッドの戻り値の型を変更すると、対応する変数を使うコードの働きも変わってきます。その例を次に示します。 private int GetWeight ( ) { return 17; } private decimal GetQuantity ( ) { return 11; } String Method() { var quantity = GetQuantity (); decimal result = GetWeight() * quantity / 4; Trace.WriteLine("result:" + result); return "result: " + result; } result:46.75 static int GetQuantity ( ) { return 11; } total:46 厳密な型付けを利用できるというメリットはありますが、暗黙的に型付けされたローカル変数を使用するとコンパイラの選択が先送りされ、コンパイル時にバグを検出できる確率が低下します。 使用時のヒント
オブジェクト初期化子オブジェクト初期化子は、C#を他の多くの高級言語と肩を並べる存在にするために当初から用意すべきだった機能です。CやC++とは異なり、C#はこれによって総合的な初期化機能を持つことになりました。この機能はおそらく、LINQをサポートするために追加された機能の中で最も広く役立つでしょう。Microsoftがオブジェクト初期化子を追加したのは、LINQステートメントが単一ステートメントだからです。これまでは、1つのステートメント内で実行できるものでなければ、オブジェクトをクエリ結果で初期化することはできませんでした。使用時のヒント
自動プロパティ自動プロパティは、バッキングストア用に単一フィールドをラップするプロパティを書くときの面倒な作業を回避するための構文糖です。C# 2.0ではプロパティを次のようにして実装しました。private int age; public int Age { get { return age; } set { age = value; } } public int Age { get ; set ; } 使用時のヒント
著者紹介Peter Ritchie(Peter Ritchie)
17年以上にわたってソフトウェア開発のプロフェッショナルとして働く。コンピュータソフトウェアとの関わりはさらに長く、最初のコンピュータはAtari 800。現在はPeter Ritchie Inc. Software Consulting Co.の社長を務め、カナダの首都地域でWindowsベースのソフトウェア開発サービスを提供している。ソフトウェア開発に関する発言とアドバイスはブログで閲覧できる。オンライン開発者コミュニティへの貢献によりMicrosoft MVP-Visual C# award(2006-2007年度)を受賞し、現在もVisual C# Developer Centerに貢献している。
|