English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

LINQ Lambda 表現式

C#3.0(.NET 3.5)はlambda式およびLINQを導入しました。lambda式は匿名メソッドを表す特殊な構文を使用する短い方法です。

例えば、以下の匿名メソッドを使用して学生がティーンエージャーかどうかを確認します:

delegate(Student s) { return s.Age >} 12 && s.Age < 20; };
Dim isStudentTeenAger = Function(s As Student) As Boolean
                                    Return s.Age > 12 And s.Age < 20
                        End Function

C#およびVB.Netでlambda表現式を使用して以下の匿名メソッドを表現できます:

s => s.Age > 12 && s.Age < 20
Function(s) s.Age  > 12 And s.Age < 20

以下の匿名メソッドからlambda表現式がどのように派生されるかを見てみましょう。

delegate(Student s) { return s.Age >} 12 && s.Age < 20; };

Lambda表現式は、まずデリゲートキーワードと引数の型を削除し、匿名メソッドにlambda演算子=>を追加することで派生されます。

匿名メソッドからのLambda表現式

上のlambda表現式は絶対に有効ですが、もし返却値の文が1つしかない場合は、大括弧、returnおよびセミコロンは必要ありません。したがって、それらを削除できます。

また、引数が1つしかない場合は、括弧()を削除できます。

匿名メソッドからのLambda表現式

したがって、以下のlambda表現式が得られます:s => s.Age > 12 && s.Age < 20 ここでsこれは引数です:=>これはlambda演算子です:s.Age > 12 && s.Age < 20これは表現主体です:

C#でのLambda表現式の構造

VB.Netでlambda表現式を取得する方法は以下のように記述できます:

VB.NetでのLambda表現式の構造

lambda表現式の呼び出し方法は、()を使用するデリゲートの呼び出し方法と同じです。

注意:VB.Netはlambda演算子=>をサポートしていません

複数の引数を持つLambda表現式

複数の引数を渡す場合は、引数を括弧で囲むことができます。以下のように:

    例:Lambda表現式中に複数の引数を指定するC#

(s, youngAge) => s.Age >= youngage;

引数の表現が明確でない場合は、各引数の型を指定することもできます:

(Student s, int youngAge) => s.Age >= youngage;
例:Lambda表現式中に複数の引数を指定するVB.Net
Function(s, youngAge) s.Age >= youngAge

引数のないLambda表現式

lambda表現式には少なくとも1つの引数を持つ必要はありません。lambda表現式は引数を何も持たないこともできます。

() => Console.WriteLine("無引数のlambda表現式")

Lambda表現式の主体には複数の文が含まれる

主体に複数の文を含めるには、式を大括号で括ります:

(s, youngAge) =>{
  Console.WriteLine("主体に複数の文を含むLambda表現式");
    
  Return s.Age >= youngAge;}
Function(s, youngAge)
    
    Console.WriteLine("主体に複数の文を含むLambda表現式")
    
    Return s.Age >= youngAge
End Function

Lambda表現式の主体内でローカル変数を宣言する

表現式の主体内で変数を宣言して、主体のどこでもそれを使用することができます。以下のように:

s =>
{ int youngAge = 18;
    Console.WriteLine("主体に複数の文を含むLambda表現式");
    return s.Age >= youngAge;
}
Function(s) 
                                      
        Dim youngAge As Integer = 18
            
        Console.WriteLine("主体に複数の文を含むLambda表現式")
            
        Return s.Age >= youngAge
            
End Function

Lambda表現式は、Func、Action、Predicateなどのビルドインデリゲートに割り当てられます。

Lambda表現式をデリゲートに割り当てる

lambda表現式はFunc<in T, out TResult>デリゲートタイプに割り当てられます。Funcデリゲートの最後の引数タイプは返り値のタイプであり、残りの引数は入力パラメータです。Funcデリゲートの詳細について学ぶには、C#チュートリアルのFuncデリゲート部分を参照してください。

以下のlambda表現式を考慮して、学生が十代であるかどうかを確認します。

Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;
Student std = new Student() { age = 21 }
bool isTeen = isStudentTeenAger(std);// falseを返す
Dim isStudentTeenAger As Func(Of Student, Boolean) = Function(s) s.Age > 12 And s.Age < 20
Dim stud As New Student With {.Age = 21}
Dim isTeen As Boolean = isStudentTeenAger(stud) // falseを返します。

上記の例では、FuncデリゲートはStudentタイプの最初の入力引数を期待し、戻り値のタイプは布尔値です。lambda表現 s => s.age > 12 && s.age < 20はFunc<Student, bool>デリゲート要求を満たします。以下のようになります:

Lambda表現を持つFuncデリゲート

上記のFunc <>デリゲートは以下のように函数になります。

bool isStudentTeenAger(Student s)
{
    return s.Age > 12 && s.Age < 20;
}

Actionデリゲート

Funcデリゲートとは異なり、ActionデリゲートActionデリゲートは、入力引数を持つことができます。lambda表現から値を返さない場合は、Actionデリゲートタイプを使用してください。

Action<Student> PrintStudentDetail = s => Console.WriteLine("Name: {0}, Age: ", s.StudentName, s.Age)1}
Student std = new Student() { StudentName = "Bill", Age =21}
PrintStudentDetail(std);//出力: Name: Bill, Age: 21
Dim printStudentDetail As Action(Of Student) = Sub(s) Console.WriteLine("Name: {0}, Age: ", s.StudentName, s.Age)1}
    
Dim stud As New Student With {.StudentName = "Bill", .Age = 21}
        
printStudentDetail(stud)//出力: Name: Bill, Age: 21

LINQクエリ内のLambda表現

通常、lambda表現式はLINQクエリと一緒に使用されます。可挙動する静的クラスには、Func<TSource,bool>を受け入れるIEnumerable<T>の拡張メソッドが含まれます。したがって、Where()拡張メソッドIEnumerable<Student>はFunc<Student,bool>を使用して収集される必要があります。以下のようになります:

Where拡張メソッドのFuncデリゲート引数

したがって、今では、Funcデリゲートに割り当てられたLambda表現を拡張メソッドWhere()に以下のようにメソッド構文で渡すことができます:

IList<Student> studentList = new List<Student>{...};
Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;
var teenStudents = studentList.Where(isStudentTeenAger).ToList<Student>();
IList<Student> studentList = new List<Student>{...};
Func<Student, bool> isStudentTeenAger = s => s.age > 12 && s.age < 20;
var teenStudents = from s in studentList
                   where isStudentTeenAger(s)
                   select s;

VB.Netでは同じ方法でFuncデリゲートを渡すことができます。

覚えておくべきポイント

  1. Lambda表現は、匿名メソッドを表す短縮方法です。

  2. Lambda表現文法: パラメータ => 表現主体

  3. Lambda表現は、ゼロ引数を持つことができます。

  4. Lambda表現の括号()には複数の引数が含まれることができます。

  5. Lambda表現は、大括号{}の中の主体表現式に複数の文を含むことができます。

  6. Lambda表現は、Func、Action、Predicateデリゲートに割り当てられます。

  7. Lambda Expressionは、デリゲートとして呼び出すことができます。