japan.internet.com The Internet & IT Network


RSSニュース検索
カテゴリ
> トップページ
> Webビジネス
> Eコマース
> Webファイナンス
> Webマーケティング
> パブリック
> Webテクノロジー
> 携帯・ワイヤレス
> Linux Today
> Linux Tutorial
> J.I.C.ブログ
キャリア
> 転職ならen
> 派遣ならen
> アルバイトならen
> IT求人情報
ヘッドライン
> 今日のヘッドライン
> 週間ヘッドライン
Special Link
> フォトコミュニティ
> ストックフォト
> クリップアート
> イラスト
> フェリカ
> Web2.0
> 写真
イベント&セミナー
> イベントカレンダー
> 書評「IT の耳」
> 出張・接待検索
> ニュースガジェット 注目
無料ニュースメール
> 新規登録
> 変更・解除
> オプトインメールの登録・変更・解除
インフォメーション
> パートナーサイト
転職ならエン
就職ならen
求人ならen
履歴書ならen
アルバイトならエン
CRM/SFAならオラクル
> グループ会社
株式会社アエリア
(株)サンゼロミニッツ
株式会社エアネット
> お問い合わせ
> 広告掲載について
> リンクについて
> 著作権について
> その他お問い合わせ
> 利用規約
> 個人情報保護方針
> 会社概要地図
デベロッパー 2008年5月13日 10:00
デベロッパー・バックナンバー
C# 3.0の新しい構文:デザインガイドライン

著者: Peter Ritchie  オリジナル版を読む プリンター用 記事を転送
2008年5月13日 10:00 付の記事
海外internet.com発の記事
このエントリーを含むはてなブックマーク この記事をクリップ! Buzzurlにブックマーク Yahoo!ブックマークに登録 newsing it!

はじめに

 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#で採用しようとしたものです。

 ラムダ式はラムダ計算に基づいています。

使用時のヒント

  • 同じコードを繰り返し使用する場合はラムダ式よりもメソッドを優先する。
  • C# 2.0では匿名デリゲートが適切と思われる場合はラムダ式を優先する。

拡張メソッド

 おそらく大いに賛否が分かれそうな追加構文の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"));
 このIsStringPluralメソッドはStringオブジェクトで動作します(与えられたコンテキストで対象の語や句が複数形であるかどうかを判断するメソッドであると考えてください)。拡張メソッドを使用すると、同様のメソッドをクラスに関連付け、そのクラスのメンバと同じように呼び出すことができます。たとえば、StringクラスにIsPluralという拡張メソッドを作成するときには、IsStringPluralメソッド宣言の元の構文を大きく変更する必要はありません。パラメータリストにthisキーワードを追加するだけです。

public static bool IsPlural(this String text,
   CultureInfo cultureInfo)
{/* ... */}
 この拡張メソッドは、次のようにして呼び出します。

String text = "languages";
Boolean isPlural = text.IsPlural(
   new CultureInfo("en"));
 このメソッド呼び出し構文では、読みやすさは向上しているかもしれませんが、メソッド定義元の追跡は困難になっています。IsPlural拡張メソッドを呼び出すコード行を見ても、IsPluralメソッドが実際にはStringクラスのメンバでないことはわかりませんし、このメソッドが実際にどのクラス内で宣言されているのかもわかりません。

 拡張メソッドは通常の静的メソッドとまとめて扱われ、次のように使用できます。

String text = "languages";
Boolean isPlural = StringExtensions.IsPlural(text,
   new CultureInfo("en"));
 拡張メソッドは、ラムダ式と組み合わせて、簡潔で非常に可読性の高いクエリ式を提供する目的に使用されることが期待されています。

 拡張メソッドの主な難点は、名前解決の問題です。基本的にすべての拡張メソッドはグローバルで、名前も引数の数も同じメソッドは今のところ区別できません。そのため、拡張メソッドはもともとネームスペースの適切な運用を妨げる性質を持っており、現時点では、スコープを明確に区切る方法はありません。つまり、ファイルにusingステートメントを追加するだけで、コンパイルエラーが発生する可能性があります。

使用時のヒント

  • 拡張メソッドは慎重に使用する。
  • 拡張メソッドは固有の静的クラス内に配置する。
  • 特定のクラスを拡張するすべての拡張メソッドを1つの静的クラスにまとめ、そのクラスに「<ClassName>Extensions」という名前を付ける。名前の衝突が起き、静的メソッドの呼び出し構文を使わざるを得ない場合は、最終的に可読性が低下しないようにする。
  • 名前の衝突が起きる可能性を低くするため、拡張メソッドのクラスを固有のネームスペース内に保存する(名前の衝突が起きると、再び静的メソッドの呼び出しを使用せざるを得なくなる)。
編集部注
 この記事の初出は『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;
 上記のコードを実行すると、「Cannot implicitly convert type 'long' to 'int'」(long型からint型への暗黙的変換はできません)という少々わかりにくいエラーメッセージが表示されます。このエラーメッセージでlong型と言及されているのは、コンパイラによってuint型からlong型への変換が暗黙的に行われるためです。つまり、コンパイラは以下の処理を実行しています。

int result = (long)unsignedNumber * signedNumber
 これは、符号あり整数と符号なし整数で二項演算を行う1つの方法です。しかし、結果をint型にする必要があるのに、コンパイラはlong型をint型に暗黙的に変換できません。そのため警告が生成されます。

 結果の型を指定するのにint型の代わりにvarを使用すると、エラーは解決します。

var result = unsignedNumber * signedNumber;
 これで正常に実行されますが、結果はuint型でもint型でもなく、long型です。また、これはulong型でもありません。

 もう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
 ここでGetQuantityメソッドに手を加え、値をint型で返すようにすると、次のようになります。

static int GetQuantity ( )
{
   return 11;
}
 結果はこうなります。

total:46
 変更した部分はごくわずかです。GetQuantityメソッドの本体には手を加えていませんが、出力は戻り値の型に応じて変わります。

 厳密な型付けを利用できるというメリットはありますが、暗黙的に型付けされたローカル変数を使用するとコンパイラの選択が先送りされ、コンパイル時にバグを検出できる確率が低下します。

使用時のヒント

  • 組み込み型でvarを使用することは避ける。
  • 結果が組み込み型ではないLINQステートメントでのみ使用する。
  • 明示的な型のローカル変数を優先する。

オブジェクト初期化子

 オブジェクト初期化子は、C#を他の多くの高級言語と肩を並べる存在にするために当初から用意すべきだった機能です。CやC++とは異なり、C#はこれによって総合的な初期化機能を持つことになりました。この機能はおそらく、LINQをサポートするために追加された機能の中で最も広く役立つでしょう。Microsoftがオブジェクト初期化子を追加したのは、LINQステートメントが単一ステートメントだからです。これまでは、1つのステートメント内で実行できるものでなければ、オブジェクトをクエリ結果で初期化することはできませんでした。

使用時のヒント

  • 1ステートメント1プロパティ方式でオブジェクトまたはエレメントを初期化するよりも、オブジェクト初期化子を優先する。

自動プロパティ

 自動プロパティは、バッキングストア用に単一フィールドをラップするプロパティを書くときの面倒な作業を回避するための構文糖です。C# 2.0ではプロパティを次のようにして実装しました。

private int age;
public int Age
{
   get
   {
      return age;
   }
   set
   {
      age = value;
   }
}
 それほど長いコードではありませんが、多くのプロパティを実装する必要がある場合は面倒になるでしょう。C# 3.0では、次のような方法で、バッキングストア用のフィールドを宣言せずにプロパティを作成できます。

public int Age
{
   get ;
   set ;
}
 バッキングストアで使われるフィールドはコンパイラによって自動生成されますが、これを直接操作することはできません。このプロパティへのすべてのアクセスは、プロパティのgetterメソッドとsetterメソッドを介して行う必要があります。

使用時のヒント

  • パブリックフィールドよりも自動プロパティを優先する。
  • パフォーマンスが重視される場合は自動プロパティを避ける。
 Microsoftは特定の理由から多くの新しいC# 3.0の構文を作成しましたが、開発者は適用可能であればいつでも新機能を使用できます。このガイドラインでは、新しいC# 3.0の構文を使用するときに陥りがちな落とし穴とそれを回避するために役立つアドバイスを示しましたが、絶対に守らなければならない規則ではありません。状況によっては、明確な理由を持ってこのガイドラインに違反することもあるでしょう。しかし一般的には、新しいC# 3.0の構文の理解を深め、より良いコードを書くためにこのガイドラインが役に立つはずです。

著者紹介

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に貢献している。


関連記事
  • 迅速で安価なアプリケーション開発を可能にする『SaaSWizard』
  • NEC と住商情シス、次世代リッチクライアント開発環境「Curl」の販売で協業
  • 【中国】政府部門が介入、オンライン B2C 市場競争が激化
  • 【中国】eBay が利用料を無料へ、C2C 戦争の幕開け
  • ロジテックダイレクトで、シンクライアント端末導入キットを限定販売


  • 関連テーマ
  • Microsoft


  • ★最新トップニュース
    海外 【MobileContentToday】Apple が再び市場シェア拡大画像のある記事(携帯・ワイヤレス 7月19日 12:00)
    Macintosh プラットフォームはまだ、iPhone の七光り効果に喜んでいるだろうか? そうとは言いがたいところだ。しかし、CNET 発のニュースによると、Windows があまり期待していない間に、Apple はデスクトップ市場においてシェア拡大を続けたようだ。
    コラム あらゆるゲームを Web カムを使って操作するための「CamSpace」(Webビジネス 7月19日 09:00)
    CamSpace は Web カムをゲームのコントローラーとして使うためのミドルウェアのようだ。
    国内 au 携帯「Wooo ケータイ」「G’zOne」「Cyber-shot ケータイ」を19日発売画像のある記事(携帯・ワイヤレス 7月18日 18:10)
    KDDI、沖縄セルラーは、2008年7月18日、au 携帯電話の新ラインアップとして、「Wooo ケータイ W62H」(日立製作所製)、「G’zOne W62CA」(カシオ計算機製)、および「Cyber-shot ケータイ W61S」(ソニー・エリクソン製)の新カラーを7月19日に全国一斉発売すると発表した。
    国内 松下電工 IS、Egenera ユーザーから販売代理店に(Webファイナンス 7月18日 17:50)
    松下電工 IS では、2004年から Egenera BladeFrame システムを使用しており、国内のユーザー企業では初めて、イージェネラと販売代理店契約を締結した。
    海外 【中国】中国電信、2008年 CDMA 事業投資、およそ300億元を予定(Webファイナンス 7月18日 17:40)
    7月17日、中国国内メディアの報道によれば、中国電信(チャイナ・テレコム)は2008年 CDMA 事業へ270億〜300億元(約4,181億4,630万―4,646億700万円)を投資する予定を明らかにした。
    トピックス
    > オススメのIT系求人情報【毎週月曜日更新】
    footer_301.gif


    リサーチ
    > デイリーリサーチDLサイト
    > OnlineResearchPortal (リサーチデータバンク)
    > モバイルリサーチ with goo
    footer_301.gif
    キーワード
    > iPhone > Youtube
    > Google > モバイルノート
    > 半導体 > ウィルコム
    > テーマ一覧はこちら
    footer_301.gif
    セミナー情報
    > 第1回インターネットコムマーケティングセミナー「新規クライアントを効率的に獲得する Web マーケティング手法とは」(3月26日)多数のご参加ありがとうございました
    footer_301.gif
    デベロッパー
    > DevX
    > CodeGuru
    > developer.com
    footer_301.gif
    日本Oracle
    footer_301.gif
    j.i.c.ブログ
    ブログ一覧
    Graphic Design Forum 【Graphic Design Forum】
    あなたはどちら? (7月18日)
    データメーション 【データメーション】
    いよいよ個人的になる問題(7月18日)
    ジュピターメディア創設者がITを斬る 【ジュピターメディア創設者がITを斬る】
    Alan を探せ(7月18日)
    ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」 【ベンチャー専門家の目利きブログ「なぜこの企業は伸びるのか?」】
    「『訪問歯科診療』のパイオニア」/デンタルサポート株式会社(7月15日)
    エンジニアの独り言 【エンジニアの独り言】
    iPhone 買いました。(7月15日)
    デスマーチからの脱却 【デスマーチからの脱却】
    mod_rewriteを使ったiPhone対応(7月12日)
    footer_301.gif
    最新コラム一覧
    百式のネットビジネス研究 百式のネットビジネス研究

    あらゆるゲームを Web カムを使って操作するための「CamSpace」(7月19日)
    DevX DevX

    PerformancePoint 2007: Planning Serverのインストール(7月18日)
    最新ハイテク講座 最新ハイテク講座

    10万馬力どころじゃない! 小型ノート PC を超安くした「Atom」(7月18日)
    アイレップの SEO スタンダード アイレップの SEO スタンダード

    PC SEO 対策とモバイル SEO 対策5つの相違点(7月18日)
    「IT の耳」 「IT の耳」

    【書評】『グリーン IT』――コスト削減と温暖化対策を両立する IT 効率化の戦略(7月17日)
    週刊-サイト別アクセス状況データ 週刊-サイト別アクセス状況データ

    ビデオリサーチインタラクティブ調査(月間インターネットオーディエンスデータ)(7月17日)
    気になるトレンド用語 気になるトレンド用語

    ニコニコ動画の命運も左右する? MAD 動画(7月16日)
    ウチのサイトを SEO ウチのサイトを SEO

    そもそも SEO ってなに?(7月16日)
    エンジニア転職ノウハウ開発室 エンジニア転職ノウハウ開発室

    約6割が残業規制に満足?エンジニア残業代の実態調査(7月15日)
    アイレップの SEM フロンティア アイレップの SEM フロンティア

    マーケットデータ取得で発見する SEM の新展開(7月15日)
    footer_301.gif
    専門チャンネル
    > セキュリティチャネル > テレコムチャネル
    > サーチエンジンウォッチ
    footer_301.gif
    海外のインターネットコム アメリカ韓国ドイツトルコ
    関連企業のサイト:ストックフォト イラスト ネットストリート ホテル予約サイト タウン情報 出張 事業継承 シミュレーション トランクルーム 優待映画チケット 田舎暮らしガイド オリジナルデザインTシャツ ニタコエ
    Copyright 2008 Jupitermedia Corporation All Rights Reserved. http://www.internet.com/
    space.gif space.gif