C# Local Functions - Visual Studio 2017

C# Local Functions - Visual Studio 2017

C# Local Functions are a great new feature in C# 7. Local functions are nested functions. They are methods declared in another method and run in the context of that method. They are methods that are used only by one other method and help to keep each method small and focused.

For example, I use local functions quite a bit in Python with recursive functions that require a bit of initialization and set-up. This shields the caller from the burden of initialization as well as helps encapsulate / abstract away details of an algorithm.

C# Local Function - Recursive C# Palindrome Function

A good and simple example of using a local function in C# is a function to determine if a word is a palindome. A palindrome is a word that spells the same forwards and backwards (e.g. 'racecar'). There are many ways to determine if a word is a palindrome, but let's say this is an interview question for a new junior developer job and you are required to write it as a recursive function in C# using a local function.

Below is one way to leverage a recursive C# local function, IsPalindrome, within another function, IsWordPalindrome.

/// <summary>
/// Determines if a single word is a palindrome.
/// </summary>
/// <param name="word">a word</param>
/// <returns>true if palindrome, otherwise false</returns>
static bool IsWordPalindrome(string word) {
    if (word == null)
        throw new ArgumentNullException(nameof(word));

    if (word.Length < 2)
        return true;

    return IsPalidrome(0, word.Length - 1);

    bool IsPalidrome(int lo, int hi) {
        if (lo >= hi)
            return true;

        if (char.ToUpperInvariant(word[lo]) !=
            char.ToUpperInvariant(word[hi]))
            return false;

        return IsPalidrome(lo + 1, hi - 1);
    }
}

Inside IsWordPalindrome is a recursive, local function, called IsPalindrome, that compares each character in a word with its mirror image. For a single word to be a palindrome, these characters must be equal.

Notice the outer function does a bit of simple argument checking and initialization before calling the local function, which is able to stay focused on character by character comparison within the word.

C# Local Function - Recursive Fibonacci Memoization

Another example of using local functions in C# 7 is for use in memoization of the classic recursive Fibonacci Sequence, where the developer is asked to find the nth Fibonacci number. This is a classic job interview question for junior developers.

Most developers have come across this programming challenge, because the recursive algorithm for finding the nth Fibonacci number is the poster child for naive algorithms. This is a classic discussion in all computer science algorithm courses as to why algorithms matter.

One way to improve performance of recursive Fibonacci in C# is to use a dictionary to store known values of Fibonacci numbers and to return these values as opposed to recalculating them over and over again. Here is an example in C# 7 that uses a local function, FibMemo, to perform the calculation.

/// <summary>
/// Returns the nth Fibonacci Number. n >= 0.
/// </summary>
/// <param name="n">The nth Fibonacci number to return.</param>
/// <returns>The nth Fibonacci number.</returns>
static int Fib(int n) {
    if (n < 0)
        throw new ArgumentException("n must be >= 0", nameof(n));

    var memo = new Dictionary<int, int>() { { 0, 0 }, { 1, 1 } };

    return FibMemo(n);

    int FibMemo(int number) {
        if (memo.ContainsKey(number))
            return memo[number];

        var value = FibMemo(number - 1) + FibMemo(number - 2);
        memo[number] = value;
        return value;
    }
}

Just like the function IsWordPalindrome, the function Fib does a bit of argument checking and initializes the memoization container before calling the local function, FibMemo, to calculate the nth Fibonacci number. Each function stays small and focused, allowing the developer to easily understand their responsibilities.

Conclusion

Although both C# local function examples deal with recursive functions and merely perform simple argument checking and initialization / set-up, there are many other examples on how and why to use local functions in C# 7. Recursive functions, like calculating the nth Fibonacci number and checking if a word is a palindrome, are easy to describe and implement in C# to drive home the usefulness.

As I mentioned, I find local functions in Python quite handy in production applications as well as solving programming challenges for job interviews. They are quite useful when solving computer science algorithm challenges.

If you're interested in other C# 7 tutorials, you may be interested in another of my favorite C# 7 features, new and improved tuples in C# 7 and Vsual Studio 2017.