What does the phrase "delegate is cached" mean in this context (and in general what a cached delegate is and what it is for):

"In case of calling SomeMethod(OtherMethod) - a delegate will always be created. In case of calling SomeMethod(x => OtherMethod(x)) - the delegate will be cached."?

Context from here

UPD

Between the first call and the second there is a difference in MSIL 'e, namely this code:

 static void SomeMethod(Func<int, int> otherMethod) { otherMethod(1); } static int OtherMethod(int x) { return x; } static void Main(string[] args) { SomeMethod(OtherMethod); // 1 SomeMethod(x => OtherMethod(x)); // 2 SomeMethod(x => OtherMethod(x)); // 3 } 

Will be converted to approximately the following:

 static void Main() { SomeMethod(new Func<int, int>(OtherMethod)); if (C.foo != null) SomeMethod(C.foo) else { C.foo = new Func<int, int>(c, Cb) SomeMethod(C.foo); } if (C.foo1 != null) SomeMethod(C.foo1) else { C.foo1 = new Func<int, int>(c, C.b1) SomeMethod(C.foo1); } } [CompileGenerated] class C { public static C c; public static Func<int, int> foo; public static Func<int, int> foo1; static C() { c = new C(); } C(){} public int b(int x) { return OtherMethod(x); } public int b1(int x) { return OtherMethod(x); } } 

But as you can see, the compiler for 3 calls created and initialized a new "cached" variable, and did not use the old

  • Try asking the user mayorovp, who wrote in this thread of comments on Habré, he also has it on ru-so - AK
  • the delegate will be cached below there is a clarification if possible - Grundy
  • @Grundy, this raises even more questions: when is it possible and when is it not? And the old questions (what kind of animal is this?) Does not respond ( - Qutrix
  • 3
    @LmTinyToon, on the other hand, the generated code just shows that the method has been cached (saved) in a static class field. - Grundy
  • 2
    @LmTinyToon, not really. in your examples - you create albeit the same, but two lambdas. If you call the method SomeMethod(x => OtherMethod(x)) not inside Main , but inside another function. For example, Wrapper , then with several calls to this function, the cached version should be used - Grundy

1 answer 1

The topic under discussion is a feature of code generation of the current version of the Microsoft .NET framework.

The code discussed is as follows:

 class Program { static void SomeMethod(Func<int, int> otherMethod) { otherMethod(1); } static int OtherMethod(int x) { return x; } static void Main(string[] args) { SomeMethod(OtherMethod); // 1 SomeMethod(x => OtherMethod(x)); // 2 } } 

In this case, the current call

 SomeMethod(OtherMethod); // 1 

compiled into an analogue of this:

 SomeMethod(new Func<int, int>(Program.OtherMethod)); 

(the fact is that OtherMethod is not a delegate, but a method, so the compiler and kindly substituted the creation of a delegate). A challenge

 SomeMethod(x => OtherMethod(x)); // 2 

- To the analogue of this (about LambdaClass see here ):

 Func<int, int> f = LambdaClass.cached_f; // cached_f - невидимое статическое поле в классе LambdaClass, который содержит лямбду if (f == null) { f = LambdaClass.cached_f = new Func<int, int>(LambdaClass.method_f); } Program.SomeMethod(f); 

That is, the value of the delegate ( Func<int, int> ) is indeed cached.

But I would not attach much importance to this fact: code generation even changes in Microsoft .NET over time ( here are recent changes in code generation of lambdas, but the team ’s perplexity that counted on its undocumented features in its code), and code generation in other implementations has the right differ and even more so.

  • five
    Here's a nice addition from Lippert himself (I duplicated the question) stackoverflow.com/questions/41922512/… - LmTinyToon
  • @LmTinyToon: And really, Eric's wonderful answer, thanks for asking! - VladD
  • one
    @LmTinyToon, yes, thanks for the translation of the question (there was also shown the benefits of such caching). And to the question "why the methods are not static" - it seems to you, I think you need to read the implementation of closures from VlaD . Simply put: a static method cannot access non-static fields (captured variables), but it needs it - Qutrix