Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local function vs Lambda C# 7.0

People also ask

Are local functions Good C#?

A great feature of C# 7.0 are local functions. Local functions have the syntax of methods and can be used within the scope of methods, properties, constructors…

Is there lambda function in C?

Significance of Lambda Function in C/C++ Lambda Function − Lambda are functions is an inline function that doesn't require any implementation outside the scope of the main program. Lambda Functions can also be used as a value by the variable to store.

Which is faster regular function and lambda function?

Lambda functions are inline functions and thus execute comparatively faster.

What is the use of local functions?

Local functions are private methods of a type that are nested in another member. They can only be called from their containing member. Local functions can be declared in and called from: Methods, especially iterator methods and async methods.


This was explained by Mads Torgersen in C# Design Meeting Notes where local functions were first discussed:

You want a helper function. You are only using it from within a single function, and it likely uses variables and type parameters that are in scope in that containing function. On the other hand, unlike a lambda you don't need it as a first class object, so you don't care to give it a delegate type and allocate an actual delegate object. Also you may want it to be recursive or generic, or to implement it as an iterator.

To expand on it some more, the advantages are:

  1. Performance.

    When creating a lambda, a delegate has to be created, which is an unnecessary allocation in this case. Local functions are really just functions, no delegates are necessary.

    Also, local functions are more efficient with capturing local variables: lambdas usually capture variables into a class, while local functions can use a struct (passed using ref), which again avoids an allocation.

    This also means calling local functions is cheaper and they can be inlined, possibly increasing performance even further.

  2. Local functions can be recursive.

    Lambdas can be recursive too, but it requires awkward code, where you first assign null to a delegate variable and then the lambda. Local functions can naturally be recursive (including mutually recursive).

  3. Local functions can be generic.

    Lambdas cannot be generic, since they have to be assigned to a variable with a concrete type (that type can use generic variables from the outer scope, but that's not the same thing).

  4. Local functions can be implemented as an iterator.

    Lambdas cannot use the yield return (and yield break) keyword to implement IEnumerable<T>-returning function. Local functions can.

  5. Local functions look better.

    This is not mentioned in the above quote and might be just my personal bias, but I think that normal function syntax looks better than assigning a lambda to a delegate variable. Local functions are also more succinct.

    Compare:

    int add(int x, int y) => x + y;
    Func<int, int, int> add = (x, y) => x + y;
    

In addition to svick's great answer there is one more advantage to local functions:
They can be defined anywhere in the function, even after the return statement.

public double DoMath(double a, double b)
{
    var resultA = f(a);
    var resultB = f(b);
    return resultA + resultB;

    double f(double x) => 5 * x + 3;
}

If you also wonder how to test local function you should check JustMock as it has the functionality to do it. Here is a simple class example that will be tested:

public class Foo // the class under test
{ 
    public int GetResult() 
    { 
        return 100 + GetLocal(); 
        int GetLocal () 
        { 
            return 42; 
        } 
    } 
}

And here is how the test looks:

[TestClass] 
public class MockLocalFunctions 
{ 
    [TestMethod] 
    public void BasicUsage() 
    { 
        //Arrange 
        var foo = Mock.Create<Foo>(Behavior.CallOriginal); 
        Mock.Local.Function.Arrange<int>(foo, "GetResult", "GetLocal").DoNothing(); 

        //Act 
        var result = foo. GetResult(); 

        //Assert 
        Assert.AreEqual(100, result); 
    } 
} 

Here is a link to JustMock documentation.

Disclaimer. I am one of the developers responsible for JustMock.