C# の LINQ ステートメントでのラムダ式

Naila Saad Siddiqui 2024年2月15日
  1. C# での LINQ
  2. C# での LINQ の構文
  3. C# のラムダ式
  4. LINQ でのラムダ式
C# の LINQ ステートメントでのラムダ式

この簡単な記事は、LINQ Select クエリのラムダ式に関するものです。 そのために、最初に LINQ、その構文、およびラムダ式の簡単な紹介について説明します。

さらに、LINQ Select クエリでラムダ式を使用する方法について説明します。

C# での LINQ

LINQ は、Language Integrated Query の頭字語です。 オブジェクト、XML、SQL データ サーバー、データ セットなどの複数のデータ ソースからデータをクエリするための統一された形式です。

そのデータ ソースの唯一の要件は、IEnumerable<T> インターフェイスを実装することです。

LINQ には複数の利点があります。

  1. LINQ は、データの発信元に関係なく、言語に統合されたオブジェクト ベースのクエリを提供します。 したがって、LINQ を使用して、データベース、XML、およびコレクションに対してクエリを実行できます。
  2. コンパイル時の構文チェック。
  3. VB や C# などのアプリケーションのネイティブ言語で、SQL を使用してデータベースにクエリを実行するのと同じように、配列や列挙可能なクラスなどのコレクションにクエリを実行できます。

数値のリストがあり、10 未満の数値を選択する必要があるシナリオを考えてみましょう。次に、LINQ クエリを使用してデータを選択できます。

以下のコード セグメントを見てみましょう。

using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleApp6 {
  class Program {
    static void Main(string[] args) {
      List<int> listOfNumbers = new List<int>() { 16, 11, 2, 5, 9, 8, 7, 6, 1, 12 };
      var result = from l in listOfNumbers
          where l<10 select l;
      foreach (int i in result) Console.WriteLine(i);
    }
  }
}

上記の LINQ クエリから、これが SQL データベースからデータをクエリするために使用するクエリ構文に似ていることがわかります。 ここでは、ローカル データ メンバー List からデータをクエリしています。

コード セグメントの出力は次のようになります。

LINQの出力

C# での LINQ の構文

LINQ でのプログラミング中に使用される LINQ の構文は 2つあります。

  1. クエリ構文
  2. メソッドの構文

LINQ でのクエリ構文

LINQ クエリ構文は、.NET Framework バージョン 3.5 以降で定義された一連のクエリ キーワードで構成されます。 これにより、プログラマーまたは開発者は、引用符を使用せずに SQL スタイルのコマンドをコード (C# または VB.NET) で記述できます。

これは、クエリ式構文とも呼ばれます。

from キーワードは LINQ クエリ構文を開始し、Select または GroupBy キーワードで終了します。 キーワードに続いて、フィルタリング、グループ化などのさまざまな標準クエリ操作を使用して、ニーズを満たすことができます。

次の例では、クエリ構文を使用してリストからデータを取得します。

using System;
using System.Linq;
using System.Collections.Generic;

class LinqExample {
  static public void Main() {
    List<string> myList = new List<string>() { "Cat", "Dog", "Tiger", "Wolf" };

    // Create LINQ Query
    var result = from a in myList select a;

    // Executing the query
    foreach (var r in result) {
      Console.WriteLine(r);
    }
  }
}

これにより、次の出力が生成されます。

クエリ構文の出力

LINQ のメソッド構文

メソッド構文は、LINQ で Enumerable または Queryable 静的クラスの拡張メソッドを呼び出すために使用されます。 メソッド拡張構文とも呼ばれます。

一方、コンパイラはコンパイル時に常にクエリ構文をメソッド構文に変換します。 SelectWhereGroupByJoinMax などの標準的なクエリ演算子を使用できます。

クエリ構文を使用せずに直接呼び出すことができます。

以下の例では、メソッド構文を使用して、名前の長さが 3 を超える動物の名前を取得します。クエリは次のように形成されます。

var result = myList.Where(a => a.Length > 3);

メソッド構文の完全なコードは次のようになります。

using System;
using System.Linq;
using System.Collections.Generic;

class LinqExample {
  static public void Main() {
    List<string> myList = new List<string>() { "Cat", "Dog", "Tiger", "Wolf" };

    // Create LINQ Query
    var result = myList.Where(a => a.Length > 3);

    // Executing the query
    foreach (var r in result) {
      Console.WriteLine(r);
    }
  }
}

これにより、次の出力が得られます。

メソッド構文の出力

メソッドの構文で、=> 記号で構成される Where 関数の引数の式に気付くかもしれません。 この珍しいことは、ラムダ式として知られています。

次のセクションでは、Lambda 式とその LINQ クエリでの使用について説明します。

C# のラムダ式

C# では、ラムダ式は無名関数と同様に使用されますが、ラムダ式を使用するときに入力する値の型を指定する必要がないため、より柔軟になります。

すべてのラムダ式は、記号 => で表されるラムダ演算子を使用します。 入力はラムダ式の左側にあり、式は右側にあります。

ラムダ式は、次の 2つの形式に分類されます。

  1. 式ラムダ
  2. ステートメントラムダ

式ラムダ

これは、入力ステートメントと、ラムダ記号の右側で評価される式で構成されます。

input statement => expression

ステートメント ラムダ

これは、入力ステートメントと、ラムダ シンボルの右側にある一連のステートメントで構成されます。

input statements => { set of statements }

いくつかの数値で構成される List データ構造があり、すべてのリスト数値のキューブを評価する必要があるとします。 これは、ラムダ式を使用して非常に簡単に実行できます。

これは、以下のコード セグメントで実証できます。

using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp6 {
  class Program {
    static void Main(string[] args) {
      List<int> listOfNumbers = new List<int>() { 16, 11, 2, 5, 9, 8, 7, 6, 1, 12 };
      var cubes = listOfNumbers.Select(a => a * a * a);

      // Display all the cubes
      Console.Write("Cubes of the List : ");
      foreach (var val in cubes) {
        Console.Write("{0} ", val);
      }
    }
  }
}

上記のコード セグメントで、Select 関数を使用してリストから要素を選択し、ラムダ式を使用してその立方体を作成したことがわかります。

セグメントの出力は次のようになります。

ラムダ式の出力

LINQ でのラムダ式

ラムダ式と LINQ は、任意のデータ ソースからデータをクエリする方法を提供します。 LINQ Lambda 構文を使用してデータをクエリする例をいくつか示します。

プロパティとして roll_numname、および marks を持つ Student のユーザー定義クラスがあるとします。 学生のリストでいくつかのデータを初期化し、LINQ クエリとラムダ式を使用してデータをクエリします。

class Student {
  private int roll_num;
  private string name;
  private int marks;

  public int Roll_num {
    get => roll_num;
    set => roll_num = value;
  }
  public string Name {
    get => name;
    set => name = value;
  }
  public int Marks {
    get => marks;
    set => marks = value;
  }
}

Main 関数では、Student クラスのリストを作成し、そこからデータをクエリします。

static void Main(string[] args) {
  List<Student> students =
      new List<Student>() { new Student { Roll_num = 1, Name = "David", Marks = 65 },
                            new Student { Roll_num = 2, Name = "John", Marks = 90 },
                            new Student { Roll_num = 3, Name = "Dina", Marks = 87 },
                            new Student { Roll_num = 4, Name = "Leen", Marks = 43 },
                            new Student { Roll_num = 5, Name = "Krish", Marks = 57 } };
}

リストを作成した後、60 点以上の点数を持つ学生を選択し、それをユーザーに表示する必要があるとします。 そのために、ラムダ式と LINQ クエリを使用します。

Console.WriteLine("Through Lambda Expression");
IEnumerable<Student> sortedData = students.Where(x => x.Marks > 60);
foreach (var s in sortedData) Console.WriteLine(s.Roll_num + "  " + s.Name + "  " + s.Marks);

Console.WriteLine("Through LINQ query");
IEnumerable<Student> result = from s in students
    where s.Marks> 60 select s; foreach (var s in sortedData) Console.WriteLine(s.Roll_num + "  " + s.Name + "  " + s.Marks);

上記のコード セグメントでは、2つの異なる方法で同じデータを選択していることに注意してください。 Lambda ステートメントを使用すると、データのクエリが非常に簡単になり、LINQ クエリよりもコーディングが少なくて済みます。

どちらの場合も出力は同じになります。

LINQ vs ラムダ式の出力

前の例では、学生のすべてのデータを表示しました。 60 点以上を獲得した学生の名前を取得する必要がある場合、ラムダ式は次のようになります。

var stuNames = students.Where(x => x.Marks > 60).Select(x => x.Name);
foreach (var s in stuNames) Console.WriteLine(s);

これにより、学生の名前のみが返されます。 したがって、それらを IEnumerable 型に格納していません。

出力は次のようになります。

ラムダ式出力1

生徒の名前と成績が必要だとしますが、まず、成績に基づいて並べ替える必要があります。 OrderBy 関数を使用してデータを並べ替えます。

var stuNames = students.OrderBy(x => x.Marks).Select(x => new { x.Name, x.Marks });
foreach (var s in stuNames) Console.WriteLine(s.Name + "  " + s.Marks);

出力は次のようになります。

ラムダ式出力2

したがって、さまざまなメソッドがラムダ式を使用してデータをクエリできることがわかります。 ラムダ式は、膨大なデータがあり、クエリを実行したりデータにさまざまな操作を適用したりするための最小限のコーディング手順が必要な場合に役立ちます。

関連記事 - Csharp LINQ