Can someone explain to me why one is necessarily better than the other?

int M()
{
    int y;
    LocalFunction();
    return y;

    void LocalFunction() => y = 0;
}

Versus

int M()
{
    return LocalFunction();
}

int LocalFunction() {
    return 0;
}

I'm not getting the point of using the lambda expression vs just making another clear function. What the advantage of using lambda expressions?

Excuse the overly simplistic example.

  • 8
    Unfortunately, the "overly simplistic example" is why the lambda expression doesn't seem to have utility. It's only until you start making real-world, real-complexity classes that their utility comes in handy. – whatsisname Nov 5 at 17:48
  • @whatsisname - You care to elaborate? – Kyle Johnson Nov 5 at 18:53
  • 3
    The lambda expression is a red herring here. The real difference between the two blocks of code is LocalFunction. The first example uses a local function, and the second uses a regular function which is misleadingly named LocalFunction, even though it's not. You could have used a lambda in both places, or not used a lambda in both places. – Eric King Nov 5 at 19:01
  • Your question is very confusing. There is no lambda expression in either of your two examples, so I don't understand what you mean by "I'm not getting the point of using the lambda expression vs just making another clear function. What the advantage of using lambda expressions?" – Jörg W Mittag Nov 6 at 10:04

Your example is a bit too simplistic to show some of the power of local functions. Take something like this for example:

class Processor
{
    public void func(IEnumerable<MyObject> objectsToProcess)
    {
        foreach (var obj in objectsToProcess)
        {
            if (obj.IsFoo())
            {
                processEntity(obj);
                obj.PostProcessFunction();
            }
            else if (obj.IsBar())
            {
                obj.DoSomeOtherPreProcessingThings();
                processEntity(obj);
            }
            else if (obj.IsBaz())
            {
                obj.Frobinate();
            }
            else
            {
                obj.Slobrify();
                processEntity(obj);
                obj.Zorpalize();
            }
        }

        void processEntity(MyObject obj) => (obj) {
            //lots of code here you don't want to replicate
        };
    }

    //lots of other public and private methods here
}

Let's assume that the processEntity function has a fair bit of code to it, something you wouldn't want to replicate. As such, it makes perfect sense to put it into a function.

But what kind of access modifiers should it have? Let's also say that the processEntity function will never be called from the public space, so let's make it private. But let's also say that it will never get called from any other member functions either. It should still be private, but can create a bit of a maintenance hassle. If you ever want to change that private function, you need to make sure it isn't called anywhere else (not terribly hard with modern IDEs, but still a cognitive load you need to take care of). It also leaves open the possibility that future development will make use of that function, possibly in ways that will break things or in ways that don't handle many subtleties

By using a local function, it communicates the intent that it should only be used within func. It also reduces future maintenance costs by giving someone looking at the class less they have to comprehend (depending on what they are doing).

There are also other things you can do, such as using closure variables.

void func2(int productId, string name)
{
   string formatMySpecialMessage(int errorCode, int reasonCode) = (errorCode, reasonCode) => {
    return $"An error ocurred while processing a request for item {productId}: {name}.  The error was error code {errorCode}, {reasonCode}";
};
    //lots of code with many error states that would use the formatMySpecialMessage function
}

Doing something like this lets you reuse a function and some of the context of your function (the productId and name in this case) without having to pass those variables into another function all the time.

There are lots of uses for them. If you've done development in Javascript you've probably seen this. I've even used local functions like this a few times in actual production code.

To go back to your original question, there isn't much difference between the two examples. But no one is likely to need to do future maintenance on code like that. And that code is too simplistic to really warrant the use of a local function.

My understanding is that the difference is purely stylistic. The compiler will generate:

int M() 
{
    return LocalFunction();
} 

private static int LocalFunction() { return 0; }

Now you also ask about the advantage of lambda expressions, which is slightly different.

A lambda expression requires no declaration, so if we have a function which is only used in a single place, we can just write the function in that place.

Perhaps the best example is predicates in Linq.

Where you used to have to define a seperate function for every search or sort you did on a collection ie

private int compare1(obj i, obj j) { ... }

List.Sort(compare1)

you can now do it inline

List.Sort(i,j  => ...);

Sure its still stylistic and arguably less performant. but it sure is neater.

There are some differences between C# methods and lambdas, so its not purely stylistic. One example is the creation of closures. I recommend Jon Skeets Article on Closures, but the gist of it is that lambdas can be passed around as objects while still maintaining access to variables in their original context. Normal methods can't!

  • Note that there are no lambda expressions in the OP's code, in either of the two examples posted. – Jörg W Mittag Nov 6 at 10:04
  • There is one in their first code snippet! – FakeSaint Nov 6 at 20:07
  • Ahhh nevermind! I was fooled by a local function – FakeSaint Nov 6 at 20:14

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

Not the answer you're looking for? Browse other questions tagged or ask your own question.