VBラムダ式 基礎文法最速マスター

デジタルアドバンテージ 一色 政彦
2010/03/16

「★チートシート」はこちら

0. まえがき

 本稿では、小さいテーマではあるが、まだまだ慣れ親しんでいない開発者が少なくないと考えられる「ラムダ式(VB:Visual Basic)」についての基礎文法を簡潔にまとめる(C#ラムダ式についてはこちら)。「ラムダ式、どう書くんだっけ?」という場合のリファレンスとして活用していただけるとうれしい。また、ラムダ式を敬遠しているという方は、まず本稿が学び始める取っ掛かりになるかもしれない(もちろん本稿の説明は充実しておらず、すべてを学べるわけではない)。

【コラム】「○○言語 基礎文法最速マスター」とは?

 今年(2010年)に入ってインターネット上では、プログラミング言語の基本文法を簡潔にまとめた「○○言語 基礎文法最速マスター」(以降、最速マスター・シリーズ)というブログ記事が多数投稿されている。参考までに、そのいくつかを示そう(そのほかについては、こちらを参照されたい)。

 これらの最速マスター・シリーズでは、基本的に短い説明とコード(+短いコメント)という構成になっており、プログラミング言語の基礎文法全体が一覧しやすいので、学び始めるきっかけとなるだけでなく、簡易リファレンスとしても活用できる。筆者の感想では、近年、英語圏で流行しているCheat Sheet(=あんちょこ、虎の巻、早見表)に通ずるものがある。ちなみに、筆者自身も最速マスター・シリーズやCheat Sheetのファンである。

1. ラムダ式(VB)の概要

ラムダ式とは何か?

 VB言語のラムダ式(lambda expressions)とは、デリゲート(delegate)や、メソッド・ベースのLINQ文の(例えば)WhereメソッドやSelectメソッドなどの引数をシンプルに記述するために、VB 9.0(=Visual Basic 2008)以降で導入された言語仕様である。

 なおデリゲートとは、メソッドを参照するための型を定義して、その型のインスタンスをメソッドとして呼び出すための機能であり、主にイベント・ハンドラやコールバック・メソッドとして活用されている。

 メソッド・ベースのLINQ文の(例えば)Whereメソッドには下記の2種類があり、ラムダ式はそれぞれ右記の型に暗黙的に変換される(詳しくは「特集:VBプログラマーのためのLINQ超入門」を参照)。

ラムダ式で記述したイベント・ハンドラの例

 次のコードは、Windowsフォーム・アプリケーションにおけるボタンのClickイベント・ハンドラのデリゲートを通常文法で記述した例と、それをラムダ式にした例である(C#ラムダ版では匿名メソッドも説明したが、VBには匿名メソッドを作成する機能はない)。

Public Sub New()

  ……省略……
  AddHandler Button1.Click, _
    AddressOf Button1_Click

End Sub

Private Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs)

  MessageBox.Show("デリゲート!")

End Sub
通常文法で記述したイベント・ハンドラのサンプル・コード
「AddHandler Button1.Click, 」には、EventHandler型のデリゲート・インスタンスを指定する必要がある。つまり、このコード例でいえば「New EventHandler(AddressOf Button1_Click)」と記述する必要があるが、「New EventHandler( )」という記述は.NET Framework 2.0以降では省略可能となっている(つまり、「AddressOf メソッド名」を設定すればよい)。このコード例でも省略されている。

↓ ラムダ式

Public Sub New()

  ……省略……
  AddHandler Button1.Click, _
    Function(sender, e) MessageBox.Show("ラムダ!")

End Sub
ラムダ式で記述したイベント・ハンドラのサンプル・コード

ラムダ式で記述したLINQ文の例

 次のコードは、コンソール・アプリケーションにおけるメソッド・ベースのLINQ文のデリゲートを通常文法で記述した例と、それをラムダ式で記述した例である。

Sub Main()

  Dim dataSource = Enumerable.Range(1, 100)

  Dim query = dataSource.Where(AddressOf WhereMethod)

  For Each num In query
    Console.WriteLine(num)
  Next

End Sub

Function WhereMethod(ByVal i As Integer) As Boolean

  Return i Mod 13 = 0

End Function
通常文法で記述したLINQ文のサンプル・コード
Whereメソッドには、Func(Of TSource, Boolean)デリゲート型の引数を指定する(Whereメソッドには、異なる引数を受け取るオーバーロード・メソッドが存在する)。

↓ ラムダ式

Sub Main()

  Dim dataSource = Enumerable.Range(1, 100)

  Dim query = dataSource.Where(Function(i) i Mod 13 = 0)

  For Each num In query
    Console.WriteLine(num)
  Next

End Sub
ラムダ式で記述したLINQ文のサンプル・コード

2. ラムダ式(VB)の基礎文法

ラムダ式の基本構文

Function(左辺) 右辺
ラムダ式の基本構文

 詳細は後述するが、VB 10(=Visual Basic 2010)以降では「Function」キーワードのほかに、「Sub」キーワードも利用できる。

ラムダ式構文の左辺

 左辺には、デリゲートとして呼び出されるメソッドのパラメータが入る(「入力パラメータ」と呼ばれる)。パラメータは ( ) で囲む必要がある。パラメータが複数の場合、各パラメータは「,」で区切る。

Function() 右辺                 // パラメータがない場合
Function(param) 右辺            // パラメータが1つの場合
Function(param1, param2) 右辺   // パラメータが2つ以上の場合
ラムダ式の基本構文

 パラメータでは通常、型はコンパイラによって自動的に推論されるので、上記のように型指定を行わない。しかし必要があれば、型指定を行うことも可能だ。

Function(param As Integer) 右辺  // パラメータの型指定
パラメータにint型を指定した例(特殊なケース)

左辺:パラメータの例

 冒頭のイベント・ハンドラとLINQ文のサンプル・コード(の一部)を用いて、実際にパラメータがどのように記述されるかを確認する。

AddHandler Button1.Click, Function(sender, e) <右辺>
パラメータの確認:イベント・ハンドラのサンプル・コード

 この例では、senderとeがパラメータである。もともとのデリゲート型は次のとおりだ。

Delegate Sub EventHandler(sender As Object, e As System.EventArgs)

 また、次のLINQ文の例では、「i」がパラメータである。

Dim query = dataSource.Where(Function(i) <右辺>)
パラメータの確認:LINQ文のサンプル・コード

 もともとのデリゲート型は次のとおり。上記の「i」と下記の「arg」が一致している。

Delegate Function Func(Of T, TResult)(arg As T) As TResult

ラムダ式構文の右辺

 右辺には、式か文を指定する。「文」形式のラムダ、および「Sub」キーワードは、VB 10(=Visual Basic 2010)以降で利用できる。

Function(左辺) 式

Sub(左辺) 式

Function(左辺)
  文
  文
  Return 文
End Function

Sub(左辺)
  文
  文
  文
End Sub

右辺:「式」形式のラムダ

 式(expression)とは、プログラミング・コードでいうところの「式」のことで、演算子を使った「i Mod 13 = 0」も式であれば、メソッド呼び出しの「MessageBox.Show("メソッド!")」も式である。式の最後には、改行を入れないのがポイント。

 冒頭のイベント・ハンドラとLINQ文のサンプル・コードにおけるラムダ式は、「式」形式で記述されている。

AddHandler Button1.Click, _
  Function(sender, e) MessageBox.Show("式!")
「式」形式で記述したラムダ式:イベント・ハンドラのサンプル・コード

Dim query = dataSource.Where(Function(i) i Mod 13 = 0)
「式」形式で記述したラムダ式:LINQ文のサンプル・コード

右辺:「文」形式のラムダ

 文(statement)とは、式の最後で改行したもの。文形式のラムダでは、その文は必ず Function 〜 End Function(=関数)もしくはSub 〜 End Sub(=サブルーチン)のブロックで囲む。Functionブロックでは戻り値が必要なので、Returnキーワードで返却する値を明記する。

 文形式のラムダは、VB 10(=Visual Basic 2010)以降でしか利用できないので注意してほしい。

 冒頭のイベント・ハンドラとLINQ文のサンプル・コードにおけるラムダ式を、「文」形式で記述すると次のようになる。上の式形式とよく見比べてほしい。

AddHandler Button1.Click, _
  Sub(sender, e)
    MessageBox.Show("文!")
  End Sub
「文」形式で記述したラムダ式:イベント・ハンドラのサンプル・コード

Dim query = dataSource.Where( _
  Function(i)
    Return i Mod 13 = 0
  End Function
)
「文」形式で記述したラムダ式:LINQ文のサンプル・コード

 なお、次のコード例のように、文はブロック内に複数記述できる。

AddHandler Button1.Click, _
  Sub(sender, e)
    Dim count As Integer = 3
    Dim msg = String.Format("{0}つの文です。", count)
    MessageBox.Show(msg)
  End Sub
複数の文を記述したラムダ式:イベント・ハンドラのサンプル・コード

戻り値について

 デリゲートによっては戻り値を必要としない(=Subキーワードのメソッドの)場合もある。上記のイベント・ハンドラのサンプル・コードは、戻り値を返さない例である。逆に、上記のLINQ文のサンプル・コードは、戻り値を返す(=Functionキーワードのメソッドの)例である。

 前述した「式形式のラムダ」を見ると分かるように、式形式のラムダでは戻り値を明示しない、つまりReturnキーワードは記述しないので注意してほしい。一方の文形式のラムダでは、戻り値が必要なFunctionブロックの場合、戻り値をReturnキーワードで明記する必要がある。

ラムダ式のスコープ外部にある変数やメソッドの利用

 ラムダ式では、そのスコープの外側にある変数やメソッドを利用できる。

Dim outerVariable = "外部変数"

AddHandler Button1.Click, _
  Sub(sender, e)
    Dim msg As String = outerVariable
    MessageBox.Show(msg)
  End Sub
ラムダ式のスコープ外部にある変数の利用

Public Sub New()

  ……省略……
  AddHandler Button1.Click, _
  Sub(sender, e)
    Dim msg As String = OuterMethod()
    MessageBox.Show(msg)
  End Sub

End Sub

Public Function OuterMethod() As String

  Return "外部メソッド"

End Function
ラムダ式のスコープ外部にあるメソッドの利用

ラムダ式が便利なのはVB 10から

 実際にラムダ式を使う際には、複数行の「文」形式で記述したいことも多い。これが利用できるのが、間もなく正式リリースされるVB 10(=Visual Basic 2010)からである(2010年4月13日にローンチが予定されている)。(C#言語と同じように)VB言語でも、このVB 10から本格的にラムダ式が使われるようになっていくだろう。End of Article

筆者による.NET/Azure関連の情報共有について

はてなブックマークやTwitterで、主に.NET/Windows Azure開発関連の情報共有を行っています。はてなブックマークでは、主に英語のブログへのリンク共有を行っています。Twitterでは、リンク共有に加え、簡単な投稿も行っています。どちらもフォローしたり、RSSフィードを購読したりできます。



@IT Special

- PR -

TechTargetジャパン

Insider.NET フォーラム 新着記事
  • foreachループで現在の繰り返し回数を使うには? (2017/3/23)
     LINQのSelect拡張メソッドを使用して、foreachループの中で現在が何回目の繰り返しなのか、そのインデックスを得る方法を紹介する(C# 7/VB 15対応)
  • Listの要素を並べ替えるには? (2017/3/22)
     LINQのOrderBy/ThenByなどの拡張メソッドとListクラスのSortメソッドを利用して、Listの要素を並べ替える方法を解説する
  • .NET Portability Analyzer (2017/3/21)
     .NET Portability Analyzerは、さまざまなプラットフォームをまたいだ.NETプログラムの移植性をチェックするためのツール
  • Visual Studio Previewとは? (2017/3/17)
     Visual Studio 2017のリリースと同時に始まった「Visual Studio Preview」と呼ばれる早期アクセスプログラムの概要を見ていこう
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

イベントカレンダー

PickUpイベント

- PR -

アクセスランキング

もっと見る

ホワイトペーパーTechTargetジャパン

注目のテーマ

Insider.NET 記事ランキング

本日 月間
ソリューションFLASH