7
Static lambda’s 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 lamda 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.
4
1 Answer
Reset to default
8
Because static delegates are slower than delegates to instance methods.
Here’s the source straight from the horse’s mouth: https://github.com/dotnet/roslyn/issues/20315#issuecomment-309583018
Here’s an issue I opened awhile ago that would remove the need to do this: https://github.com/dotnet/runtime/issues/58955
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.
1
-
1
Can you please give more detail in the answer itself? The sentence, "Because static delegates are slower than delegates to instance methods," seems incomplete and inadequate to me.
– Enigmativity6 hours ago
Could you please confirm that "holds a reference to the current class" is indeed true? To me it looks like
Target
points to autogenerated nested class instance (hence unrelated to "the current class")… (Also clearly at least 4 people verified the behavior and found that indeedTarget
points to the main class' instance… any of upvoters could provide details to reproduce the behavior?)10 hours ago
@AlexeiLevenkov Yes your correct, will update question.
10 hours ago
Consider to also clarify what exactly your concerns now… "Why C# creates class even my action does not have state on its own" or "Does class autogenerated for static action still refer to its "parent" class" or… (current answer could easily be "just because they can")
10 hours ago
@AlexeiLevenkov thanks for the suggestion, I added some background to my question.
9 hours ago