Introducing C# 9: Static anonymous functions
C# 9 brings an important improvement to anonymous functions by allowing the modifier static on them and we now have static anonymous functions ! Why Microsoft brought this feature ? Because allocation matters ! Microsoft explains here that lambda are not cost less (https://devblogs.microsoft.com/premier-developer/dissecting-the-local-functions-in-c-7/) :
“Anonymous methods are not cheap:”
- Overhead of a delegate invocation (very very small, but it does exist).
- 2 heap allocations if a lambda captures local variable or argument of enclosing method (one for closure instance and another one for a delegate itself).
- 1 heap allocation if a lambda captures an enclosing instance state (just a delegate allocation).
- 0 heap allocations only if a lambda does not capture anything or captures a static state.
In the example below the contextual variable _text (instance variable) is captured by the anonymous function and can cause unintended allocation:
To fix that you can add the modifier static on the lambda and use const modifier on the variable you don’t want to be captured, in that way any enclosing context will be captured there:
Microsoft details on that page all the rule that apply to this feature: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/static-anonymous-functions
Among these here are the most important ones:
- A lambda or anonymous method may have a static modifier. The static modifier indicates that the lambda or anonymous method is a static anonymous function.
- A static anonymous function cannot capture state from the enclosing scope. As a result, locals, parameters, and this from the enclosing scope are not available within a static anonymous function.
- A static anonymous function cannot reference instance members from an implicit or explicit this or base reference.
- A static anonymous function may reference static members from the enclosing scope.
- A static anonymous function may reference constant definitions from the enclosing scope.