LINQ をサポートする Visual Basic の機能
更新 : 2007 年 11 月
統合言語クエリ (LINQ: Language-Integrated Query) という名前は、Visual Basic 2008 の新しいテクノロジを指します。これはクエリ構文とその他の新しい言語構成要素を言語内で直接サポートします。LINQ があると、外部データ ソースに対してクエリを実行するために新しい言語を学習する必要がなくなります。Visual Basic を使用して、リレーショナル データベース、XML ストア、またはオブジェクト内のデータのクエリを行うことができます。このようにクエリ機能を言語に統合することで、コンパイル時に構文エラーやタイプ セーフかどうかをチェックできるようになります。また、この統合によって、豊富かつ変化に富むクエリを Visual Basic 2008 で記述するために必要な知識を事前に与えられることにもなります。
以下のセクションでは、新しい言語構成要素について詳しく説明します。これを読むと、入門ドキュメント、コード例、およびサンプル アプリケーションについて読み始めることができるようになります。リンクをクリックして、言語機能が一体となって統合言語クエリを可能にするしくみに関する詳しい説明を参照することもできます。「チュートリアル : Visual Basic でのクエリの作成」から読み始めることをお勧めします。
クエリ式
Visual Basic 2008 のクエリ式は、SQL や XQuery のクエリ式に似た宣言構文で表すことができます。コンパイル時に、クエリの構文が LINQ プロバイダの標準クエリ演算子拡張メソッドの実装に対するメソッド呼び出しに変換されます。アプリケーションは、Imports ステートメントを使用して適切な名前空間を指定することで、どの標準クエリ演算子をスコープ内に入れるかを制御します。Visual Basic クエリ式の構文は次のようになります。
Dim londonCusts = From cust In customers _
Where cust.City = "London" _
Order By cust.Name Ascending _
Select cust.Name, cust.Phone
詳細については、「Visual Basic における LINQ の概要」を参照してください。
暗黙的に型指定される変数
変数を宣言して初期化するときに変数の型を明示的に指定する代わりに、次の例に示すように、コンパイラが型を推論して割り当てるようにできます。これは、ローカル型の推論と呼ばれます。
メモ : |
---|
ローカル型の推論は、メソッド本体内でローカル変数を定義していて、Option Infer が On に設定されている場合にのみ機能です。LINQ の新しいプロジェクトでは On が既定です。詳細については、「Option Infer ステートメント」を参照してください。 |
' The variable number will be typed as an integer.
Dim aNumber = 5
' The variable name will be typed as a String.
Dim aName = "Virginia"
メモ : |
---|
Visual Basic 2005 以前では、これらの例はコンパイルできましたが、aNumber と aName に割り当てられていた型はいずれも Object でした。そのため、Visual Basic 2008 で Option Infer を On に設定して既存のプロジェクトを再コンパイルすると、旧バージョンの言語のときと動作が異なる場合があります。 |
' Query example.
' If numbers is a one-dimensional array of integers, num will be typed
' as an integer and numQuery will be typed as IEnumerable(Of Integer)--
' basically a collection of integers.
Dim numQuery = From num In numbers _
Where num Mod 2 = 0 _
Select num
この方法で宣言された変数は、明示的に型を指定した変数と同じように厳密に型指定されます。ローカル型の推論により、匿名型を作成できるようになります。これは LINQ クエリで必要ですが、任意のローカル変数で使用できます。
詳細については、「ローカル型の推論」を参照してください。
オブジェクト初期化子
オブジェクト初期化子は、クエリの結果を格納するために匿名型を作成する必要があるときにクエリ式で使用されます。また、クエリ外部の名前付きの型のオブジェクトを初期化するためにも使用できます。オブジェクト初期化子を使用することにより、コンストラクタを明示的に呼び出すことなく、オブジェクトを 1 行で初期化することができます。パブリック プロパティ Name および Phone や、他にもいくつかのプロパティを持つ Customer という名前のクラスがあるとします。オブジェクト初期化子を次のように使用することができます。
Dim aCust As Customer = New Customer With {.Name = "Mike", _
.Phone = "555-0212"}
詳細については、「オブジェクト初期化子 : 名前付きの型と匿名型」を参照してください。
匿名型
匿名型を使用すると、一連のプロパティをクエリ結果に含める要素に一時的にグループ化できるので便利です。これにより、要素に名前付きのデータ型を定義せずに、クエリで使用できるフィールドを任意の組み合わせおよび任意の順序で選択できるようになります。
匿名型はコンパイラによって動的に構築されます。型の名前はコンパイラによって割り当てられます。これはコンパイルを実行するたびに変わる場合があります。したがって、名前を直接使用することはできません。匿名型は次の方法で初期化されます。
' Outside a query.
Dim product = New With {.Name = "paperclips", .Price = 1.29}
' Inside a query.
' You can use the existing member names of the selected fields, as was
' shown previously in the Query Expressions section of this topic.
Dim londonCusts1 = From cust In customers _
Where cust.City = "London" _
Select cust.Name, cust.Phone
' Or you can specify new names for the selected fields.
Dim londonCusts2 = From cust In customers _
Where cust.City = "London" _
Select CustomerName = cust.Name, _
CustomerPhone = cust.Phone
詳細については、「匿名型」を参照してください。
拡張メソッド
拡張メソッドを使用することにより、定義の外側からデータ型またはインターフェイスにメソッドを追加できます。この機能を使用すると、既存の型を実際に変更しなくても、その型に新しいメソッドを実質的に追加できます。標準クエリ演算子自体は、IEnumerable<T> を実装する任意の型で LINQ クエリ機能を実現する拡張メソッドのセットです。IEnumerable<T> の拡張メソッドとしては他にも、Count、Union、および Intersect があります。
次の拡張メソッドは、印刷メソッドを String クラスに追加します。
' Import System.Runtime.CompilerServices to use the Extension attribute.
<Extension()> _
Public Sub Print(ByVal str As String)
Console.WriteLine(str)
End Sub
メソッドは、String の通常のインスタンス メソッドのように呼び出されます。
Dim greeting As String = "Hello"
greeting.Print()
詳細については、「拡張メソッド (Visual Basic)」を参照してください。
ラムダ式
ラムダ式は、計算を実行して単一の値を返す、名前を持たない関数です。名前付きの関数とは異なり、ラムダ式は定義と実行を同時に行うことができます。次の例は 4 を表示します。
Console.WriteLine((Function(num As Integer) num + 1)(3))
ラムダ式の定義を変数名に代入した後、名前を使用して関数を呼び出すことができます。次の例も 4 を表示します。
Dim add1 = Function(num As Integer) num + 1
Console.WriteLine(add1(3))
LINQ では、ラムダ式は、多数の標準クエリ演算子の基礎になっています。コンパイラは、ラムダ式を作成して、Where、Select、Order By、Take While などの基本的なクエリ メソッドに定義された計算を取り込みます。
たとえば、次のコードは学生のリストから 4 年生をすべて返すクエリを定義します。
Dim seniorsQuery = From stdnt In students _
Where stdnt.Year = "Senior" _
Select stdnt
クエリ定義は次の例のようなコードにコンパイルされます。ここでは 2 つのラムダ式を使用して、Where および Select の引数を指定します。
Dim seniorsQuery2 = students _
.Where(Function(st) st.Year = "Senior") _
.Select(Function(s) s)
どちらの形式も For Each ループを使用して実行できます。
For Each senior In seniorsQuery
Console.WriteLine(senior.Last & ", " & senior.First)
Next
詳細については、「ラムダ式」を参照してください。