C# Academy · Lesson

Local Functions vs Lambdas

Choose between local functions and lambdas.

Lesson 4 of 413 steps

Local Functions vs Lambdas is a free C# Academy lesson on CoddyKit. This is lesson 4 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the C# Academy learning path, and your progress syncs across the web and the CoddyKit app. The C# Academy course includes 4 lessons in total.

Local Functions vs Lambdas

Both local functions and lambdas let you define small functions inside a method. They overlap a lot, but differ in syntax, capabilities, and performance. Choosing the right one keeps code clear and efficient.

Two Ways to Write a Helper

Here the same squaring helper is written both as a local function and as a lambda assigned to a delegate. Both produce the same result.

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));
    }
}

Local Functions Allow Recursion Easily

A local function can call itself by name. A lambda cannot reference its own variable during initialization, so recursion is awkward with lambdas.

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));
    }
}

Local Functions Can Be Generic

Local functions support their own type parameters. Lambdas cannot be generic, so for reusable typed helpers a local function is the choice.

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" }));
    }
}

Performance: Avoiding Delegate Allocation

A lambda assigned to a delegate may allocate a delegate object and, if it captures, a closure. A local function called directly avoids both, which matters in hot loops.

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 and ref Parameters

Local functions can declare out and ref parameters; lambdas via the common Func/Action delegates cannot. This makes try-parse helpers natural as local functions.

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);
    }
}

Lambdas Shine as Inline Arguments

When you need to pass behavior straight into a method like LINQ Where or Select, a lambda is the most concise and readable option.

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));
    }
}

Capture Works for Both

Both forms can capture enclosing variables. The difference is mostly in syntax and the allocation cost, not in whether capture is possible.

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));
    }
}

Definite Assignment and Order

A local function can be called before its declaration in the method; a lambda variable must be assigned before use. This gives local functions more flexible placement.

using System;

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

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

Choosing Between Them

Use a local function for named, reusable, recursive, generic, or hot-path helpers. Use a lambda for short, inline behavior passed directly to another method. Both are tools; pick by intent.

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));
    }
}

Try It Yourself

Use a recursive local function for the core logic and a lambda for the inline LINQ projection, letting each construct do what it does best.

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);
    }
}

Quick Check

Compare the two constructs.

Recap

Local functions and lambdas overlap but differ in key ways.

  • Local functions can be recursive, generic, and use out/ref.
  • Called directly, they avoid delegate and closure allocations.
  • Lambdas are most concise as inline arguments to methods like LINQ.
  • Choose by intent: named reusable helper vs short inline behavior.
Free to start

Learn C# with an AI tutor — free

Write and run real code in your browser, get instant help from a 24/7 AI tutor, and pick up where you left off on the web or in the app.

Courses
93
Lessons
346

Frequently Asked Questions

Is the “Local Functions vs Lambdas” lesson free?

Yes — the full text of “Local Functions vs Lambdas” is free to read here on the web. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the C# Academy course, upgrade to CoddyKit PRO. The C# Academy course includes 4 lessons in total.

What will I learn in “Local Functions vs Lambdas”?

Choose between local functions and lambdas. You practise C# Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start C# Academy?

No prior experience is required. C# Academy on CoddyKit is structured for beginners through advanced learners, so you can start here or from the beginning and move at your own pace. This is lesson 4 of 4.

How long does the “Local Functions vs Lambdas” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this C# Academy lesson?

Yes. Every C# Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. Declaring Local Functions
  2. Closures and Captured Variables
  3. Static Local Functions
  4. Local Functions vs Lambdas
← Back to C# Academy