Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

とことん理解する .NET Framework 3.5

Visual Studio 2008 徹底入門(3)

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

Visual Studio 2008と同時に.NET Framework 3.5がリリースされました。この.NET Framework 3.5に搭載されている新機能や.NET Framework 2.0、3.0からの変更点の内容を解説します。.NET Framework 3.5の機能を知ることでVisual Studio 2008の新機能や機能強化がなぜ施されているかを理解することが目標です。

はじめに

 2007年12月にVisual Studioの最新バージョンであるVisual Studio 2008(以下、VS2008)がリリースされました。これと同時に.NET Frameworkの最新バージョンである.NET Framework 3.5(以下、.NET 3.5)がリリースされました。VS2008の新機能は見た目の変化や生産性の向上に分かりやすく直結する部分などが多く、大きな注目を集めていますが、.NET 3.5にもさまざまな機能強化や新機能の追加がされています。そこでVisual Studio 2008入門の第3回となる本稿では、.NET 3.5の機能強化、新機能に注目し解説していきます。

これまでの記事

対象読者

  • Visual Studio 2008に興味がある方
  • .NET Framework 3.5に興味がある方

必要な環境と準備

 Visual Studio 2008 入門シリーズの新しい統合開発環境 Visual Studio 2008ってなんだ!?の必要な環境と準備を参考にしてください。

.NET 3.5全体像

 .NET 3.5は.NET 2.0および.NET 3.0に機能追加する形で構成されています。次の図1はそのイメージを表したものです。

図1:.NET Framework 3.5全体像
図1:.NET Framework 3.5全体像

 図1に示すように.NET 2.0の共通言語ランタイム(CLR)やベースクラスライブラリ(BCL)などのテクノロジーは.NET 3.5でも同じように利用できます。また、.NET 3.0で追加されたWPFなどの新しい4つのテクノロジーもそのまま利用できます。.NET 3.5は.NET 2.0と.NET 3.0にあるこれらのさまざまな機能を機能強化し、更にASP.NET AJAXやLINQ、言語の新機能の追加といったバージョンであると考えればよいでしょう。

 本シリーズでは、.NET 3.5で機能強化された点や新機能について扱っていきます。本稿では、ベースクラスライブラリやWindows Forms、言語機能の機能強化ポイント、および.NET 3.5の目玉でもあるLINQ(Language Integrated Query:統合言語クエリ)について紹介します。

 なお、以下の内容については別記事で解説します。

  • ASP.NET AJAX
  • Windows Presentation Foundation
  • Windows Communication Foundation
  • Windows Workflow Foundation

過去の.NET Frameworkとの関係

 図1にも示しましたが、.NET 3.5は.NET 2.0/3.0を拡張するような形で構成されています。このため、.NET 2.0でコンパイルされたアプリケーションは基本的には.NET 3.5上でも問題なく動作します。ただし、ランタイムバージョンには以下の図2に示すような関係があります(mscorlib.dllやSystem.dllなどほとんどのBCLも同様です)。

図2:.NET Frameworkとランタイムの対応
図2:.NET Frameworkとランタイムの対応

 このように.NET 2.0/3.0と.NET 3.5ではビルド番号(「メジャーバージョン.マイナーバージョン.リビジョン.ビルド」と表現する場合)に違いがあります。また、より正確には.NET 3.5は.NET 2.0/3.0を土台にしているのではなく、.NET 2.0 SP1/3.0 SP1を土台にしています。このため、よく言われる「.NET Framework 2.0でコンパイルされたアプリケーションは.NET Framework 3.5上でも動作する」は概ね正解ですが、完全ではないというところに注意が必要です。

.NET Framework 2.0のService Pack 1
 .NET 2.0でコンパイルしたアプリケーションを.NET 3.5上で動かす場合だけではなく、.NET 2.0にSP1を適用した場合も同じように注意が必要です。また.NET 2.0 SP1でコンパイルされたアプリケーションは、.NET 2.0で作られたアプリケーションよりも.NET 3.5で完全動作する可能性がより高いとも言えます。なお、Service Pack適用で修正される内容の一覧は、.NET Framework 2.0 Service Pack 1 で修正される問題および.NET Framework 3.0 Service Pack 1 で修正される問題で確認できます。

.NET 3.5の機能強化ポイント

 .NET 3.5ではベースクラスライブラリ、およびその周辺テクノロジーにさまざまな機能強化や新機能の追加がされています。ここではその中からいくつかを抜粋して紹介します。

Windowsフォームの新機能

 Windowsフォームにもいくつかの新機能が追加されています。例えば、新しい統合開発環境 Visual Studio 2008ってなんだ!?の「Windowsアプリケーション開発」で紹介している内容もWindowsフォームの新機能の1つです。ここではこれとは異なるものを紹介したいと思います。

 1つ目は「ファイルを開く」「ファイルを保存する」のダイアログに関するものです。従来は、実行するOSに合わせたウィンドウが表示されていました。Vistaは、Vista用の新しいタイプとXPと同様なタイプの2種類が利用できるため、これをプロパティで制御できるようになりました。具体的にはOpenFileDialog(SaveFileDialog)クラスのAutoUpgradeEnabledプロパティを設定します。初期値はtrueで、trueの場合はVista用のもの、falseの場合はXPと同様のタイプのものを利用します。なお、XPで実行した場合この設定は無視されます。

図3:AuthUpgradeEnabledプロパティがtrueの場合
図3:AuthUpgradeEnabledプロパティがtrueの場合
図4:AuthUpgradeEnabledプロパティがfalseの場合
図4:AuthUpgradeEnabledプロパティがfalseの場合

 次に、UACに関するものです。といってもただのアイコンの追加ですが、SystemIconsクラスにShieldプロパティが追加され、このプロパティからUACの管理者特権が必要ですという意味を示すアイコンを取得できます。

図5:アイコンをボタンに設定した例
図5:アイコンをボタンに設定した例

 なお、FileDialogのAutoUpgradeEnabledプロパティおよびSystemIconsのShieldプロパティは.NET 2.0 SP1にも追加となっています。このため、SP1なしの.NET 2.0でも利用できていたような錯覚にとらわれることがありますが、実際にはこれらのプロパティを利用したコードは実行時エラーとなってしまうため、注意が必要です。

ネットワーキングの新機能

 .NET 3.5ではピアツーピアネットワークの構築を容易に行えるようにするためのネットワーキング機能が追加されています。PNRP(Peer Name Resolution Protocol)を利用したピアツーピアネットワークの構築のために、System.Net.PeerToPeer名前空間が用意され、このネットワーク内で高度なコラボレーションを構築するために、System.Net.PeerToPeer.Collaboration名前空間が用意されています。いずれもSystem.Net.dll内にあり、.NET 3.5のみに提供されている機能です。

その他の新機能

 これら以外にクラスライブラリとして拡充されている点を簡単に紹介しておきたいと思います。

  • HashSet<T>クラス
  • 奇数のみ、偶数のみなど数学でセットと呼ばれるコレクションを高速に扱うためのクラスです
  • EventProviderクラス
  • Event Tracing for Windows(ETW)を利用するためのクラスです
  • PipeClientStream クラス
  • 匿名(AnonymousPipeClientStream)、名前付き(NamedPipeClientStream)のパイプ処理を提供するクラスです
  • ReaderWriterLockSlimクラス
  • ReaderWriterLockに変わる軽量のロック機構を提供するクラスです
  • TimeZoneInfoとDateTimeOffsetクラス
  • TimeZone、DateTimeに変わる新しいタイムゾーン処理のためのクラスです

 これら以外の新機能の詳細については、MSDNライブラリの.NET Framework 3.5の新機能も合わせて参照してください。

LINQ……その前に

 .NETが3.5になり、合わせてVisual Basicは9.0に、C#は3.0にバージョンアップしました。これによりそれぞれの言語には、言語構文としてのさまざまな新機能が追加されています。いずれも通常のプログラミングで非常に面白く、便利に利用可能なものですので、ここで紹介しておきたいと思います。

型推論

 型推論とは、実行されるコードによって変数に格納されている型をコンパイラが推論する機能です。Visual Basicでは従来から遅延バインディングという機能によって実行時に型を決定して動作する仕組みがありましたがこれとは少し意味合いが異なるものになります。以下のコードを見てください。

型推論を利用するコード(Visual Basic)
Dim s = "Hello!"
型推論を利用するコード(C#)
var s = "Hello!";

 このように、VB.NETはAs句を利用しないコードを書きます。C#は型推論される型を示すvarというキーワードを利用します。この例では、「Hello!」という文字列を設定しているため、sという変数はString型として認識されます。VS2008では型推論を利用している状態のインテリセンスも問題なく利用できます(詳細はここが違う! Visual Studio 2008を参照してください)。

 なお、型推論を利用すると人間が見た場合に、型が分かりにくくなるという欠点も備えることになります。むやみに型推論を利用しないようにしたり、変数名に分かりやすい名前をつけたりするなど利用上のルールが必要になります。

オブジェクト初期化子

 オブジェクト初期化子とは、インスタンス生成時に同時にプロパティなどの値を設定する機能です。単純には、

オブジェクト初期化子=デフォルトコンストラクタ呼び出し+プロパティ設定

 となります。オブジェクト初期化子を利用した以下のコードを見てください。

オブジェクト初期化子を利用するコード(Visual Basic)
Dim cust As Customer = New Customer() With { .Name = "libaty" }
オブジェクト初期化子を利用するコード(C#)
Customer cust = new Customer() { Name = "libaty" };

 上記のコードは次のように分解できます(C#は割愛します)。

オブジェクト初期化子を利用しないコード(VB.NET)
Dim cust As Customer = New Customer()
cust.Name = "libaty"

 引数付きコンストラクタを用意すればいいのではないか? と考えられる方もいるかもしれませんが、オブジェクト初期化子を利用した場合は、好きなプロパティ(フィールドも可)を自由に初期化できます。また、VS2008では、オブジェクト初期化子を利用する際にもインテリセンスのサポートを受けることができます。

匿名型

 匿名型とは、予め決められた型を作成せずにインスタンスを作成する機能です。予め決められた型を作成しないため、メソッドを格納することはできず、プロパティのみを持つことができます。匿名型を利用した以下のコードを見てください。

匿名型を利用するコード(VB.NET)
Dim product = New With { .Name = "チョコレート", .Price = 100 }
匿名型を利用するコード(C#)
var product = new { Name = "チョコレート", Price = 100 };

 上記のコードはインスタンスを生成するNewキーワードの直後に型名がありません。このように型名を指定せず、オブジェクト初期化子を利用して生成されるクラスを匿名型と言います。匿名型はObjectクラスを直接継承したクラスですが、型名はコンパイラが自動で決定するため、変数は型推論を利用した状態で保持する必要があります。

拡張メソッド

 拡張メソッドは既存クラスの派生クラスを作成することなく、既存クラスにメソッドを追加できる(ような)機能です。「ような」としているのは、事実上そのような利用ができるが、厳密には少し異なるためです。まずは拡張メソッドを定義した以下のコードを見てください。

拡張メソッドの定義(Visual Basic)
Module StringExtensions

    <Extension()> _
    Public Sub Print(ByVal source As String)
        Console.WriteLine(source)
    End Sub

End Module
拡張メソッドの定義(C#)
public static class StringExtensions
{
  public static void Print(this String source)
  {
    Console.WriteLine(source)
  }
}

 Visual BasicでもC#でも静的メソッドとして構成する必要がありますが、Visual Basicの場合にはさらにExtension属性を設定する必要があります。この例では、引数としてString型を設定しているため、String型のインスタンスでPrintという新しいメソッドが利用可能となります。このように特別な静的メソッドを構成し、既存のクラスに新しいメソッドを追加するのが拡張メソッドです。VS2008ではインテリセンスで拡張メソッドを表示できるので簡単に利用することができます。

ラムダ式

 ラムダ式とは、ある処理を行い、単一の結果を返却する名前を持たないメソッドを定義する機能です。このメソッドはデリゲート型として利用することができ、定義したラムダ式を変数に代入しておくことも可能です。ラムダ式を利用した場合、例えばVB.NETではAs句を利用して戻り値の型を明示的に指定することはできませんが、処理内容から戻り値の型は自動的に型推論されます。ラムダ式の記述例は以下のコードを見てください。

ラムダ式の記述例(VB.NET)
Dim func = Function(str As String) str = "libaty"
ラムダ式の記述例(C#)
// 下の1行はクラス定義として定義しておく
delegate bool MyFunc(string str);

MyFunc func = str => str == "libaty"

 この例では、String型の引数strを受け取り、引数と文字列「libaty」を比較するという処理を行うラムダ式を定義し、func変数に代入しています。これを利用する場合には、

ラムダ式で定義したメソッドの利用
Console.WriteLine(func("fujiko"))

 とすることで利用できます(この例の場合、Falseと出力されます)。このようにあるデリゲート型に対して、名前なしメソッドでインスタンスを作り、それを利用するという過程の名前なしメソッドの定義を行える機能がラムダ式になります。

LINQ

 さて、型推論、オブジェクト初期化子、匿名型、拡張メソッド、ラムダ式と、Visual BasicとC#の新しい言語機能について説明してきました。これらは単独でも利用できる強力な機能ですが、これらの機能をすべて利用して記述されるのがLINQ(Language Integrated Query:統合言語クエリ)と言われる機能です。

 通常、プログラミングをしている際には、オブジェクトや配列、データベース、DataSet、XMLなどさまざまな情報にアクセスする必要があります。従来は、アクセス対象に合わせてプログラミングをしていましたが、LINQを利用することで同じようなプログラミング方法で、異なる情報にアクセスできるようになります。

 LINQを利用する場合には大雑把に以下の3つの手順を踏みます。

  1. アクセス対象のデータソースの用意
  2. データソースに対する抽出処理
  3. 抽出データの利用

 アクセス対象のデータソースとしては、ArrayListなどのコレクション系オブジェクトや配列、SQL Serverデータベース、Xmlドキュメント、DataSetなどが利用可能です。これらのアクセス対象には、抽出処理をデータソースに対する処理に変換するLINQプロバイダというものが予め用意されているということでもあります。つまり、独自にLINQプロバイダを作成することで、どのようなデータソースに対してもLINQ技術を利用できるということになります。

 次に、データソースに対する抽出処理です。抽出処理は一般的にクエリ式というものを使って記述されます。仮にcustomersという名前のデータソースが用意されている場合、抽出処理は次のように記述できます。

LINQの例(VB.NET)
Dim query = From cust In customers _
            Where cust.City = "London" _
            Order By cust.Name Ascending _
            Select Name = cust.Name, Phone = cust.Phone
LINQの例(C#)
var query = from cust in customers
            where cust.City == "London"
            orderby cust.Name ascending
            select new { Name = cust.Name, Phone = cust.Phone };

 SQL文をご存じの場合には、順番こそ異なるものの見慣れた構文ではないかと思います。これがLINQで利用されるクエリ式と言われるものです。しかし、これはクエリ式を利用してこのようにも記述できるというだけで、実態としては次のようなコードを記述しているのと同義です。

LINQをクエリ式で書かない例(VB.NET)
Dim query = customers _
            .Where(Function(cust) cust.City = "London") _
            .OrderBy(Function(cust) cust.Name) _
            .Select(Function(cust) New With { _
            .Name = cust.Name, Phone = cust.Phone })
LINQをクエリ式で書かない例(C#)
var query = customers
            .Where(cust => cust.City == "London")
            .OrderBy(cust => cust.Name)
            .Select(cust => new { Name = cust.Name, 
                                  Phone = cust.Phone });

 ここでの、WhereOrderByなどのメソッドはコレクション系クラスなどに対する拡張メソッドです(正確にはIEnumerable(T)インターフェースに対する拡張メソッド)。このように書き直してみると、型推論、オブジェクト初期化子、匿名型、拡張メソッド、ラムダ式のすべてを総動員している集大成の技術であることがご理解いただけるかと思います。ただ、このようなさまざまな機能を利用して書いていたのでは大変なのでこれを簡略化するためにクエリ式という新しい機能を利用して、記述を簡単にしているということになります。

 最後に抽出されたデータはFor Each構文などを利用したり、WindowsフォームのDataGridViewやASP.NETのGridViewなどにそのまま利用したりといったことができます。特にASP.NETには新しいDataSourceコントロールとしてLinqDataSourceコントロールというものも用意されているので、データバインド機能の中に簡単に組み込むことができます。

まとめ

 今回は.NET Framework 3.5の新機能をいろいろな点から紹介しました。全体像や前バージョンとの互換性に関する注意点を見ることで新しい.NET Frameworkが位置するところをご理解いただけたでしょうか。クラスライブラリとして、言語そのものとして、さまざまな新機能が追加されていることがわかるかと思います。

 また、今回は細かい詳細の動作は説明できませんでしたが、LINQという大きな技術についてこれを支えている言語機能という点から紐解いて説明しました。少しとっつきにくいと思われる大型テクノロジーを理解する糸口になれば幸いです。

 次回はクライアントサイドを中心とした.NET 3.5世代のASP.NETとWebテクノロジについて解説する予定です。どうぞお楽しみに。

参考資料

  1. Visual Studio 2008 Professional Edition
  2. MSDN ライブラリ
  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

修正履歴

  • 2008/04/09 16:23 P3.ラムダ式 戻り値の型指定ができない点について訂正して追記

  • 2008/03/17 17:13 ソース「拡張メソッドの定義(C#)」のtypo修正:target => source

著者プロフィール

  • WINGSプロジェクト りばてぃ/FUJIKO/ナオキ(リバティ, フジコ, ナオキ)

    <WINGSプロジェクトについて> 有限会社 WINGSプロジェクトが運営する、テクニカル執筆コミュニティ(代表 山田祥寛)。主にWeb開発分野の書籍/記事執筆、翻訳、講演等を幅広く手がける。2018年11月時点での登録メンバは55名で、現在も執筆メンバを募集中。興味のある方は、どしどし応募頂...

  • 山田 祥寛(ヤマダ ヨシヒロ)

    静岡県榛原町生まれ。一橋大学経済学部卒業後、NECにてシステム企画業務に携わるが、2003年4月に念願かなってフリーライターに転身。Microsoft MVP for ASP/ASP.NET。執筆コミュニティ「WINGSプロジェクト」代表。 主な著書に「入門シリーズ(サーバサイドAjax/XMLD...

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5