C# local functions as explanatory variables

TL;DR; Among other use cases, local functions can be explanatory variables for short routines.

For instance this anonymous function...

private void SomeMethod()  
{
    // anonymous function
    var characters = dNormal.Where(c => 
        CharUnicodeInfo.GetUnicodeCategory(c) !=
        UnicodeCategory.NonSpacingMark);
}

...might become this local func.

private void SomeMethod()  
{
    // local func as explanatory variable
    Func<char, bool> isDiacritic = c => 
        CharUnicodeInfo.GetUnicodeCategory(c) = 
        UnicodeCategory.NonSpacingMark;

    var characters = dNormal.Where(x => !isDiacritic(x));
}

Though a local function might be better, because we aren't going to hot swap the routine with another implementation.

private void SomeMethod()  
{
    // local function as explanatory variable
    bool isDiacritic(char c) => 
        CharUnicodeInfo.GetUnicodeCategory(c) = 
        UnicodeCategory.NonSpacingMark;

    var characters = dNormal.Where(x => !isDiacritic(x));
}

Another option is to make a private static method.

// static method as explanatory variable
private static bool IsDiacritic(char c) =>  
    CharUnicodeInfo.GetUnicodeCategory(c) = 
    UnicodeCategory.NonSpacingMark;

private void SomeMethod()  
{
    var characters = dNormal.Where(x => !IsDiacritic(x));
}

Possible usage guidelines for naming routines.

  • anonymous function when the function's implementation explains itself.

  • Func/Action when we might hot swap the implementation; scope these to the method, to the class, or to the object as appropriate.

  • local function when the routine only makes sense in the context of its parent method.

  • private static method when the routine makes sense in the context of its class and/or when the routine's implementation becomes large and/or complex.

Comments? Join the conversation on Twitter.