Local function vs Lambda C # 7.0

I am considering new implementations in C # 7.0, and I'm curious that they implemented local functions, but I cannot imagine a scenario in which a local function would be preferable to a lambda expression, and what is the difference between them.

I understand that lambdas are anonymous functions, and local functions are not, but I can’t understand the real world scenario where a local function has advantages over lambda expressions

Any example would be much appreciated. Thank you

+159
function c # lambda
Dec 03
source share
4 answers

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

You need a helper function. You use it from only one function, and you probably use variables and type parameters that are in the scope of this function. On the other hand, unlike lambda, you do not need this as an object of the first class, so you do not need to specify the type of delegation and distribute the actual delegate object. You may also want it to be recursive or universal, or implement it as an iterator.

To expand it, the benefits:

  • Performance.

    When creating a lambda, a delegate must be created, which in this case is unnecessary. Local functions are really just functions, delegates are not required.

    In addition, local functions are more efficient at capturing local variables: lambdas usually captures variables in a class, while local functions can use a structure (passed using ref ), which again avoids allocation.

    It also means that calling local functions is cheaper, and they can be built-in, which may further improve performance.

  • Local functions can be recursive.

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

  • Local functions can be shared.

    Lambdas cannot be shared, because they must be assigned to a variable with a specific type (this type can use shared variables from the outer scope, but it's not the same thing).

  • Local functions can be implemented as an iterator.

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

  • Local functions look better.

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

    For comparison:

     int add(int x, int y) => x + y; Func<int, int, int> add = (x, y) => x + y; 
+252
Dec 03 '16 at 15:11
source share

In addition to svick, an excellent answer is another advantage for local functions:
They can be defined anywhere in the function, even after the return .

 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; } 
+76
Mar 31 '17 at 14:08
source share

If you are also wondering how to test a local function, you should check out JustMock as it has the functionality to do so. Here is a reference article detailing the approach.

Denial of responsibility. I am one of the developers behind JustMock .

+5
Feb 05 '19 at 7:12
source share

I use the built-in functions to avoid excessive garbage collection, especially when working with longer operating modes. Say you would like to receive 2 years or market data for a given ticker symbol. In addition, you can put together a lot of functionality and business logic, if necessary.

what he does is open a socket connection to the server and iterate over the data binding the event to the event. You can think of it the same way as for the class, only one does not write helper methods all over the place that really work only for one functionality. the following is an example of how this might look, note that I am using variables, and the methods of the β€œhelper” are below. In the end, I beautifully remove event handlers, if my Exchange class is external / injected, I would not have a registered event handler

 void List<HistoricalData> RequestData(Ticker ticker, TimeSpan timeout) { var socket= new Exchange(ticker); bool done=false; socket.OnData += _onData; socket.OnDone += _onDone; var request= NextRequestNr(); var result = new List<HistoricalData>(); var start= DateTime.Now; socket.RequestHistoricalData(requestId:request:days:1); try { while(!done) { //stop when take to long…. if((DateTime.Now-start)>timeout) break; } return result; }finally { socket.OnData-=_onData; socket.OnDone-= _onDone; } void _OnData(object sender, HistoricalData data) { _result.Add(data); } void _onDone(object sender, EndEventArgs args) { if(args.ReqId==request ) done=true; } } 

You can see the benefits as indicated below, here you can see an example implementation. Hope this helps explain the benefits.

0
Aug 22 '18 at 15:33
source share



All Articles