Static lambdas introduced in C# 9 allow us to mark a lambda expression as static to prevent it from capturing instance state.
However when you check the .Target property on the lambda it is still set, which is different to when you set an Action to a static method which has no target.
Action action = static () => Console.WriteLine("test");
if(action.Target != null)
{
// action unexpectedly holds a reference
}
Background: I'm trying to make a eventing system (not tied to the current event syntax) that uses weak references without needing reflection (MethodInfo). I was checking that .Target was null, but that doesn't work for static lambda, where the static lambda .Target is set to a nested singleton.
Because static delegates are slower than delegates to instance methods.
Here's the source straight from the horse's mouth: Comment on issue "Lambda method with no capture in static class generates instance method"
Here's an issue I opened awhile ago that would remove the need to do this: [fastthis] Delegate performance being eaten up by not passing this in dedicated register
The reason is deep in the guts of calling conventions. All delegate invocations are member function calls on the delegate method. In the ancestral platform, a static delegate compiled to only two instructions (pop
and jmp
indirect); however modern platforms pass arguments in registers rather than on the stack. This means an instance delegate invocation can compile to two instructions (mov
and jmp indirect
); however a static delegate has to compile to generate entire stack frame and copy all arguments, so it can remove the instance parameter from the argument list.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With