C# Static Local Function — Complete Guide
In this tutorial, you'll learn about C# Static Local Function. We cover key concepts, practical examples, and best practices.
Your local function does not capture any variables from the enclosing scope, but the compiler still generates a closure class, allocating garbage every call. The static keyword on a local function guarantees no capture and eliminates the allocation.
Wrong
public IEnumerable<int> ProcessData(int[] items)
{
return items.Where(IsValid);
bool IsValid(int x) => x > 0; // No capture — but compiler may still allocate
}
Output: Works, but the compiler creates a closure instance each time ProcessData is called, even though IsValid does not capture any variables.
Right
public IEnumerable<int> ProcessData(int[] items)
{
return items.Where(IsValid);
static bool IsValid(int x) => x > 0; // Guaranteed no allocation
}
Output: Same result, zero allocation. The static keyword forces the compiler to verify the function does not reference this or any local variables.
If you try to capture with a static local function:
public IEnumerable<int> ProcessData(int[] items, int min)
{
return items.Where(IsValid);
static bool IsValid(int x) => x > min; // CS8820: Cannot reference local variable
}
Output: Compiler error CS8820 telling you to remove static or pass min as a parameter.
Prevention
- Mark local functions
staticwhen they do not capture enclosing variables. - Pass captured values as parameters instead of closing over them.
- Use
staticlocal functions inside hot paths (loops, LINQ callbacks, tight iterations). - Combine with lambda conversion — the static local function can be converted to a delegate without allocation in some cases.
- Profile before optimizing — one allocation per call is usually fine; avoid it in high-throughput code.
Common Mistakes with static local function
- Forgetting
deriving (Show, Eq)on custom data types needed for debugging - Placing the wildcard pattern first in case expressions, making all subsequent patterns unreachable
- Using
headandtailinstead of pattern matching, causing runtime errors on empty 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
Static local functions are used in high-performance paths in Durga Antivirus Pro's pattern matching engine. For more C#, visit DodaTech.
Built by the developers of DodaTech
Doda Browser, DodaZIP & Durga Antivirus Pro