C# Academy · レッスン

ローカル関数とラムダの比較

ローカル関数とラムダのどちらを使うか判断します。

レッスン 4/413 ステップ

「ローカル関数とラムダの比較」はCoddyKit上の無料C# Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはC# Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 C# Academyコースには全4レッスンが含まれています。

ローカル関数とラムダ式

ローカル関数とラムダ式はどちらも、メソッド内に小さな関数を定義するために使えます。共通する部分は多いものの、構文、機能、パフォーマンスには違いがあります。適切な方を選ぶことで、コードを明確かつ効率的に保てます。

ヘルパーを記述する2つの方法

ここでは、同じ二乗計算のヘルパーを、ローカル関数とデリゲートに代入したラムダ式の両方で記述します。どちらも同じ結果を生成します。

using System;

public class Program
{
    public static void Main()
    {
        int SquareFn(int n) => n * n;       // local function
        Func<int, int> squareLambda = n => n * n; // lambda

        Console.WriteLine(SquareFn(4));
        Console.WriteLine(squareLambda(4));
    }
}

ローカル関数では再帰を簡単に使える

ローカル関数は名前を使って自分自身を呼び出せます。ラムダ式は初期化中に自身の変数を参照できないため、ラムダ式での再帰は扱いにくくなります。

using System;

public class Program
{
    public static void Main()
    {
        // Clean recursion with a local function
        int Factorial(int n) => n <= 1 ? 1 : n * Factorial(n - 1);
        Console.WriteLine(Factorial(5));
    }
}

ローカル関数はジェネリックにできる

ローカル関数は独自の型パラメーターをサポートします。ラムダ式はジェネリックにできないため、再利用可能で型付きのヘルパーにはローカル関数が適しています。

using System;

public class Program
{
    public static void Main()
    {
        T First<T>(T[] items) => items[0]; // generic local function

        Console.WriteLine(First(new[] { 9, 8, 7 }));
        Console.WriteLine(First(new[] { "a", "b" }));
    }
}

パフォーマンス:デリゲートの割り当てを避ける

デリゲートに代入したラムダ式では、デリゲートオブジェクトが割り当てられることがあり、キャプチャする場合はクロージャも割り当てられます。ローカル関数を直接呼び出せば両方を避けられるため、頻繁に実行されるループで重要になります。

using System;

public class Program
{
    public static void Main()
    {
        // Direct call, no delegate or closure allocation
        static int Add(int a, int b) => a + b;

        int total = 0;
        for (int i = 0; i < 5; i++) total = Add(total, i);
        Console.WriteLine(total);
    }
}

out と ref のパラメーター

ローカル関数では out と ref のパラメーターを宣言できますが、一般的な Func/Action デリゲートを使うラムダ式では宣言できません。そのため、TryParse ヘルパーはローカル関数として記述するのが自然です。

using System;

public class Program
{
    public static void Main()
    {
        bool TryGetFirstDigit(string s, out int digit)
        {
            digit = 0;
            foreach (var c in s)
                if (char.IsDigit(c)) { digit = c - '0'; return true; }
            return false;
        }

        if (TryGetFirstDigit("abc4", out int d))
            Console.WriteLine(d);
    }
}

インライン引数でラムダ式が活躍

LINQ の Where や Select のようなメソッドに処理を直接渡す場合、最も簡潔で読みやすい選択肢はラムダ式です。

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

public class Program
{
    public static void Main()
    {
        var nums = new List<int> { 1, 2, 3, 4, 5, 6 };
        var evens = nums.Where(n => n % 2 == 0).Select(n => n * 10);
        Console.WriteLine(string.Join(", ", evens));
    }
}

どちらもキャプチャに対応

どちらの形式でも、外側のスコープにある変数をキャプチャできます。違いは主に構文と割り当てコストにあり、キャプチャできるかどうかではありません。

using System;

public class Program
{
    public static void Main()
    {
        int bonus = 10;
        int WithBonusFn(int n) => n + bonus;     // captures
        Func<int, int> withBonusLambda = n => n + bonus; // captures

        Console.WriteLine(WithBonusFn(5));
        Console.WriteLine(withBonusLambda(5));
    }
}

確定代入と順序

ローカル関数はメソッド内で宣言する前に呼び出せますが、ラムダ式を格納する変数は使用前に代入されていなければなりません。そのため、ローカル関数のほうが配置の自由度が高くなります。

using System;

public class Program
{
    public static void Main()
    {
        Console.WriteLine(Triple(4)); // allowed before declaration

        int Triple(int n) => n * 3;
    }
}

どちらを選ぶか

名前を付けて再利用する処理、再帰処理、ジェネリック処理、またはホットパスのヘルパーには ローカル関数を使用してください。別のメソッドに直接渡す短いインライン処理には ラムダ式を使用してください。どちらも手段なので、意図に応じて選択します。

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

public class Program
{
    public static void Main()
    {
        static bool IsPrime(int n)
        {
            if (n < 2) return false;
            for (int i = 2; i * i <= n; i++)
                if (n % i == 0) return false;
            return true;
        }

        var primes = Enumerable.Range(2, 20).Where(IsPrime);
        Console.WriteLine(string.Join(", ", primes));
    }
}

自分で試す

中心となるロジックには再帰的なローカル関数を使用し、インラインの LINQ 投影にはラムダ式を使用して、それぞれの構造の得意分野を活かしてください。

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

public class Program
{
    public static void Main()
    {
        // Local function: recursive, named, reusable
        static int DigitCount(int n) => Math.Abs(n) < 10 ? 1 : 1 + DigitCount(n / 10);

        var nums = new List<int> { 5, 42, 1000, 7, 88 };
        // Lambda: concise inline projection
        var report = nums.Select(n => n + " has " + DigitCount(n) + " digits");
        foreach (var line in report) Console.WriteLine(line);
    }
}

簡単な確認

2 つの構造を比較してください。

まとめ

ローカル関数とラムダ式には共通点がありますが、重要な違いもあります。

  • ローカル関数は再帰的およびジェネリックにでき、out/refも使用できます。
  • 直接呼び出す場合、デリゲートやクロージャの割り当てを回避できます。
  • ラムダ式は、LINQ のようなメソッドへのインライン引数として最も簡潔です。
  • 意図に応じて選択します。名前付きで再利用可能なヘルパーか、短いインライン処理かで判断してください。
無料で開始

AI チューターと学ぶ C# — 無料

ブラウザでリアルコードを書いて実行し、24/7 の AI チューターから瞬時にサポートを受け、ウェブまたはアプリで続きから学習できます。

コース
93
レッスン
346

よくある質問

「ローカル関数とラムダの比較」レッスンは無料ですか?

はい。「ローカル関数とラムダの比較」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、C# Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 C# Academyコースには全4レッスンが含まれています。

「ローカル関数とラムダの比較」で何を学びますか?

ローカル関数とラムダのどちらを使うか判断します。 ブラウザで直接実行するハンズオンコードでC# Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

C# Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのC# Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ローカル関数とラムダの比較」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このC# Academyレッスンでコードを書いて実行できますか?

はい。すべてのC# Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. ローカル関数の宣言
  2. クロージャーとキャプチャされた変数
  3. 静的ローカル関数
  4. ローカル関数とラムダの比較
← C# Academyに戻る