Basically the first is an anonymous method defined by a delegate (user guide). In the case the delegate is predefined with the signature used. Then your "content" can be "stored" in a variable, as it was done.
The readonly
was used to prevent its contents from being exchanged. One of the great advantages of using delegates (in this case using a lambda) is to be able to exchange content (which must be executed) and give flexibility to the application. In this specific case where this is not possible, I do not see so much advantage, of course it depends on the context where it is used, there are situations that can be interesting, including avoid some project patterns such as Strategy, for example.
The return
is unnecessary there in the header, could have written like this:
(numA, numB) => total += numA + numB;
I put in the Github for future reference.
The second is a normal method handled by the language. It has better compiler support and can be used in more situations.
The first has some generic usage limitations that the second does not have. The second, in general, will be called by the Soma()
and must be available in context. The first will be called by the name of the variable holding a reference to this code body. And this can be passed on to other contexts. It is even possible to play the normal method in a variable that expects a method with the same signature, but is less common.
The result does not change anything. The performance of the first is slightly lower because there is a indirect and has an closure. Also consumes a little more memory.
A delegate is a type that has a pointer to the code to be executed and to the variables it encloses (in case a total
, but in the other example it has this cost too). It is a given, it is an object, and every object occupies memory. The method call has to query this stored address before, causing the indirect and extra processing cost. Moreover, being an indirect is more complicated, if not impossible to make certain optimizations. The direct method is all solved by the compiler and has no overhead. See a test.
The local variables of a normal method are placed in the stack. In the delegated method they are in the heap (within that object created to support the delegate/closure) since they need to be available in other contexts.
The former has greater difficulty in choosing Overload if it has methods with different signatures/default Arguments. The decision is better in normal methods.
I may be wrong, but I see little need for syntax to be this complex. I think the code could be simplified. It seems to me that the first one is trying to simulate a class as well. It also doesn’t need the return
in the latter case.