LINQ をサポートする Visual Basic の機能
統合言語クエリ (LINQ) という名前は、Visual Basic のテクノロジを指します。これはクエリ構文とその他の言語構成要素を言語内で直接サポートします。 LINQ があると、外部データ ソースに対してクエリを実行するために新しい言語を学習する必要がなくなります。 Visual Basic を使用して、リレーショナル データベース、XML ストア、またはオブジェクト内のデータのクエリを行うことができます。 このようにクエリ機能を言語に統合することで、コンパイル時に構文エラーやタイプ セーフかどうかをチェックできるようになります。 また、この統合によって、豊富かつ変化に富むクエリを Visual Basic で記述するために必要な知識を事前に与えられることにもなります。
以下のセクションでは、LINQ をサポートする言語構成要素について詳しく説明します。これを読むと、入門ドキュメント、コード例、およびサンプル アプリケーションについて読み始めることができるようになります。 リンクをクリックして、言語機能が一体となって統合言語クエリを可能にするしくみに関する詳しい説明を参照することもできます。 「チュートリアル: Visual Basic でクエリを記述する」から読み始めることをお勧めします。
クエリ式
Visual Basic のクエリ式は、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 ステートメント」および「ローカル型の推論 (Visual Basic)」を参照してください。
ローカル型推論の例を次に示します。 この例を使用するには、Option Infer を On に設定する必要があります。
' The variable aNumber will be typed as an integer.
Dim aNumber = 5
' The variable aName will be typed as a String.
Dim aName = "Virginia"
ローカル型の推論はこのセクションで後述LINQ クエリで必要な匿名型を作成することもできます。
次の LINQ の例では、型の推論は Option Infer が On か Off かにかかわらず実行されます。 Option Infer が Off で、Option Strict が 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
オブジェクト初期化子
オブジェクト初期化子は、クエリの結果を格納するために匿名型を作成する必要があるときにクエリ式で使用されます。 また、クエリ外部の名前付きの型のオブジェクトを初期化するためにも使用できます。 オブジェクト初期化子を使用することにより、コンストラクターを明示的に呼び出すことなく、オブジェクトを 1 行で初期化することができます。 パブリック プロパティ Name および Phone や、他にもいくつかのプロパティを持つ Customer という名前のクラスがあるとします。オブジェクト初期化子を次のように使用することができます。
Dim aCust = New Customer With {.Name = "Mike",
.Phone = "555-0212"}
詳細については、「オブジェクト初期化子: 名前付きの型と匿名型 (Visual Basic)」を参照してください。
匿名型
匿名型を使用すると、一連のプロパティをクエリ結果に含める要素に一時的にグループ化できるので便利です。 これにより、要素に名前付きのデータ型を定義せずに、クエリで使用できるフィールドを任意の組み合わせおよび任意の順序で選択できるようになります。
匿名型はコンパイラによって動的に構築されます。 型の名前はコンパイラによって割り当てられます。これはコンパイルを実行するたびに変わる場合があります。 したがって、名前を直接使用することはできません。 匿名型は次の方法で初期化されます。
' 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
詳細については、「匿名型 (Visual Basic)」を参照してください。
拡張メソッド
拡張メソッドを使用することにより、定義の外側からデータ型またはインターフェイスにメソッドを追加できます。 この機能を使用すると、既存の型を実際に変更しなくても、その型に新しいメソッドを実質的に追加できます。 標準クエリ演算子自体は、IEnumerable を実装する任意の型で LINQ クエリ機能を実現する拡張メソッドのセットです。IEnumerable の拡張メソッドとしては他にも、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
詳細については、「ラムダ式 (Visual Basic)」を参照してください。