Local functions C# with Example
Local functions are defined within a method and aren't available outside of it. They have access to all local variables and support iterators, async/await and lambda syntax. This way, repetitions specific to a function can be functionalized without crowding the class. As a side effect, this improves intellisense suggestion performance. Example double GetCylinderVolume(double radius, double height) { return getVolume(); double getVolume() { // You can declare inner-local functions in a local function double GetCircleArea(double r) => Math.PI * r * r; // ALL parents' variables are accessible even though parent doesn't have any input. return GetCircleArea(radius) * height; } } Local functions considerably simplify code for LINQ operators, where you usually have to separate argument checks from actual logic to make argument checks instant, not delayed until after iteration started. Example public static IEnumerable Where( this IEnumerable source, Func predicate) { if (source == null) throw new ArgumentNullException(nameof(source)); if (predicate == null) throw new ArgumentNullException(nameof(predicate)); return iterator(); IEnumerable iterator() { foreach (TSource element in source) if (predicate(element)) yield return element; } } Local functions also support the async and await keywords. Example async Task WriteEmailsAsync() { var emailRegex = new Regex(@"(?i)[a-z0-9_.+-]+@[a-z0-9-]+\.[a-z0-9-.]+"); IEnumerable emails1 = await getEmailsFromFileAsync("input1.txt"); IEnumerable emails2 = await getEmailsFromFileAsync("input2.txt"); await writeLinesToFileAsync(emails1.Concat(emails2), "output.txt"); async Task> getEmailsFromFileAsync(string fileName) { string text; using (StreamReader reader = File.OpenText(fileName)) { text = await reader.ReadToEndAsync(); } return from Match emailMatch in emailRegex.Matches(text) select emailMatch.Value; } async Task writeLinesToFileAsync(IEnumerable lines, string fileName) { using (StreamWriter writer = File.CreateText(fileName)) { foreach (string line in lines) { await writer.WriteLineAsync(line); } } } } One important thing that you may have noticed is that local functions can be defined under the return statement, they do not need to be defined above it. Additionally, local functions typically follow the "lowerCamelCase" naming convention as to more easily differentiate themselves from class scope functions.