C# Local Function — Complete Guide
In this tutorial, you'll learn about C# Local Function. We cover key concepts, practical examples, and best practices.
A method has a helper operation that only it uses. You create a private method in the class, cluttering the namespace and making the helper visible to other methods that should not call it. Local functions let you define a function inside another function.
Wrong
public class ReportGenerator
{
public string GenerateReport(IEnumerable<int> data)
{
return string.Join(", ", data.Select(TransformItem));
}
private string TransformItem(int x) => $"Item: {x}"; // Visible to entire class
}
Output: Works, but TransformItem is callable by any method in the class. It should be private to GenerateReport.
Right
public class ReportGenerator
{
public string GenerateReport(IEnumerable<int> data)
{
string TransformItem(int x) => $"Item: {x}"; // Only visible here
return string.Join(", ", data.Select(TransformItem));
}
}
Output: Same result. TransformItem is scoped to the enclosing method.
Local functions can access variables from the enclosing method (closures), support async, use generics, and can appear inside constructors, properties, and other local functions.
public int Factorial(int n)
{
if (n < 0) throw new ArgumentException("Negative input");
return LocalFact(n);
int LocalFact(int x) => x <= 1 ? 1 : x * LocalFact(x - 1);
}
Prevention
- Use local functions for helper logic that is only relevant to one method.
- Use local functions in iterators and async methods to validate arguments eagerly.
- Use static local functions (C# 9) when you do not need closure access.
- Avoid deep nesting — one or two levels of local functions is the practical limit.
- Extract shared logic into private methods when two or more methods need it.
- Use local functions for recursive helpers that should not be part of the public API.
Common Mistakes with local function
- Non-exhaustive pattern matches that compile with warnings then crash at runtime
- Misunderstanding that
Stringis[Char]with poor performance for large text operations - Using
foldlinstead offoldl'causing stack overflow on large lists
These mistakes appear frequently in real-world CSHARP code. DodaTech's contributors have identified these patterns through analysis of open-source projects and production systems.
Practice Exercise
Write a pure function that safely divides two integers using Maybe, then test it with edge cases like division by zero and negative numbers.
This exercise reinforces the concepts covered in this guide. Try implementing it before checking online solutions.
FAQ
Local functions are used in Doda Browser's extension validation pipeline for parsing rules. For more C# patterns, visit DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro