X

Local functions in C# 7.0

One of new features of C# 7.0 is support for local functions. Local functions are methods that are defined inside other methods to simplify more complex code and by example to support local recursion. This blog post shows how to use local functions in C# 7.0 and gives some advice in context of technical design of code.

To illustrate local function I will use finding of factorial as an example.

class Program
{
    static void Main(string[] args)
    {
        var i = 6;

        int Factorial(int n)
        {
            if (n == 0)
                return 1;
            else
                return n * Factorial(n - 1);
        }

        Console.WriteLine(Factorial(i));
        Console.ReadLine();
    }
}

Now one may ask why I use recursive call for factorial as it is not so efficient as using for-loop? Let’s move to for-loop.

class Program
{
    static void Main(string[] args)
    {
        var i = 6;

        int Factorial(int n)
        {
            var result = n;

            for (var counter = n - 1; counter >= 1; counter--)
            {
                result = result * counter;
            }

            return result;
        }

        Console.WriteLine(Factorial(i));
        Console.ReadLine();
    }
}

Now we have more effective method for finding factorials. But it is a simple for-loop. Why should we put it local function?

I think it’s good idea in the means of technical design. This for-loop has one concrete meaning – find the factorial – and this is why I prefer to communicate this fact to developer who is working on the code after me.

How to organize the code?

Now let’s see where we should put local functions in our methods. What I suggest here is my personal opinion. Most important part of every method is method body. So, this is coming as first thing. As we name local functions with informative and descriptive names we can keep these functions in the bottom part of method.

To illustrate my idea the modified version of factorial example is here.

class Program
{
    static void Main(string[] args)
    {
        // method body
        if(args.Length == 0)
        {
            Console.WriteLine("Missing argument: input value as integer");
            return;
        }

        var i = int.Parse(args[0]);
      
        Console.WriteLine(Factorial(i));
        Console.ReadLine();

        // local functions
        int Factorial(int n)
        {
            var result = n;

            for (var counter = n - 1; counter >= 1; counter--)
            {
                result = result * counter;
            }

            return result;
        }
    }
}

Now we have code organized and we benefit from this little trick if we use it everywhere in our codebase where local functions are used.

Some considerations of local functions

Some things to keep in mind when considering local functions:

  1. Local functions are part of methods where they are defined and they should not contain any system-wide logic.
  2. Local functions are not visible to other classes and therefore they are tested as unit with methods that own them.
  3. Use local functions only if there is real need for this.
  4. Don’t over-use local functions as you may end up with too long methods that are hard to test.

Wrapping up

Local functions are nice feature in C# 7.0 and there are situations where local functions help us to write cleaner code. Still local functions are not a thing to use to shorten or reorganize the code that doesn’t need them. This can heppen when working with spaghetti code. Consider well if local function is needed before going with this and try it out if it seems like solution. Be aware that local functions are not testable as they are considered to be same local unit with containing method.

Liked this post? Empower your friends by sharing it!

View Comments (12)

  • Hi,

    what's the advantage of declaring a local function instead of creating an Action or Func as a variable of your method? I guess the aim is to move C# toward a TypeScripty syntax (that is itself moving toward a C-sharpy syntax), but I don't really see the added value, except, maybe, the readability of the code. And even this does not hold as now, we have expression body that replace usual method declarations syntax by lambda expression so...

  • Your factorial method shouldn't be local as it's something that could obviously be shared elsewhere. You don't provide a compelling argument for the need for local functions at all. What was the point?

  • To address both replies so far:

    Lambdas are more limited than functions. For instance, they cannot do yield return. I wish they'd fix those inconsistencies, but the simpler syntax here is still nice. The yield return problem is actually one of the more compelling use cases for local functions. Generator methods (methods that do yield return) are entirely lazy, which is a problem for doing parameter validation (the validation won't happen when you call the method, but instead will occur when you MoveNext on the enumerable for the first time). For this reason it's a common pattern to break such functions in two with a public function that does the validation and then calls a non-public version that does the iteration. This is ugly, though, and you don't really want any other code to ever call the helper method. Declaring it as a local function solves all of these issues. There's other use cases as well, but this is the most compelling.

  • Oh, I should have also said in the case of lambdas (Action, Func, etc.) you have to allocate a delegate, which has a runtime cost in both performance and memory, even if it's small. With local functions there's no cost here.

  • Here is a use case for local functions that I consider more compelling.

    void MyFunction()
    {
    void HandleException()
    {
    //cleanup code here
    }

    try
    {
    //operation that can fail here
    }
    catch (IOException)
    {
    HandleException();
    }
    // many other catch clauses all handled the same way
    catch (NotSupportedException)
    {
    HandleException();
    }
    }

  • This website features various prescription drugs for ordering online.
    Users can easily buy essential medicines from anywhere.
    Our catalog includes popular treatments and targeted therapies.
    Everything is sourced from licensed providers.
    https://community.alteryx.com/t5/user/viewprofilepage/user-id/568982
    We ensure discreet service, with data protection and fast shipping.
    Whether you're filling a prescription, you'll find what you need here.
    Begin shopping today and enjoy stress-free healthcare delivery.

  • On this platform, you can discover a wide selection of casino slots from leading developers.
    Players can enjoy retro-style games as well as new-generation slots with stunning graphics and interactive gameplay.
    Even if you're new or an experienced player, there’s a game that fits your style.
    play aviator
    All slot machines are ready to play anytime and compatible with laptops and mobile devices alike.
    All games run in your browser, so you can jump into the action right away.
    Site navigation is easy to use, making it quick to browse the collection.
    Sign up today, and dive into the world of online slots!

  • Here, you can easily find real-time video interactions.
    Interested in engaging dialogues career-focused talks, this platform has a solution tailored to you.
    The video chat feature developed for bringing users together globally.
    With high-quality video along with sharp sound, every conversation feels natural.
    You can join open chat spaces or start private chats, according to what suits you best.
    https://rt.cams18.ru/couples
    The only thing needed is a stable internet connection and a device start connecting.

  • On this site, explore an extensive selection virtual gambling platforms.
    Searching for classic games latest releases, there’s a choice to suit all preferences.
    The listed platforms checked thoroughly for trustworthiness, enabling gamers to bet with confidence.
    1xbet
    Moreover, the site offers exclusive bonuses and deals targeted at first-timers including long-term users.
    Thanks to user-friendly browsing, discovering a suitable site takes just moments, saving you time.
    Stay updated about the latest additions through regular check-ins, as fresh options appear consistently.

  • ¿Quieres cupones vigentes de 1xBet? En nuestra plataforma descubrirás las mejores ofertas para tus jugadas.
    El promocódigo 1x_12121 garantiza a hasta 6500₽ durante el registro .
    Para completar, utiliza 1XRUN200 y disfruta una oferta exclusiva de €1500 + 150 giros gratis.
    https://myworldgo.com/forums/1/news-and-announcements/topic-create
    No te pierdas las ofertas diarias para acumular más beneficios .
    Los promocódigos listados son verificados para hoy .
    Actúa ahora y potencia tus apuestas con la casa de apuestas líder !

  • Searching for exclusive 1xBet discount vouchers? Our website is your go-to resource to unlock valuable deals designed to boost your wagers.
    For both beginners or a seasoned bettor , the available promotions provides maximum benefits during registration .
    Keep an eye on seasonal campaigns to maximize your rewards.
    https://roomstyler.com/users/888starzbet
    All listed codes are tested for validity to work seamlessly this month .
    Take advantage of limited-time opportunities to transform your odds of winning with 1xBet.

Related Post