Lambdas are nice, as they offer brevity and locality and an extra form of encapsulation. Instead of having to write functions which are only used once you can use a lambda.
While wondering how they worked, I intuitively figured they are probably only created once. This inspired me to create a solution which allows to restrict the scope of a class member beyond private to one particular scope by using the lambda as an identifier of the scope it was created in.
This implementation works, although perhaps overkill (still researching it), proving my assumption to be correct.
A smaller example:
class SomeClass
{
public void Bleh()
{
Action action = () => {};
}
public void CallBleh()
{
Bleh(); // `action` == {Method = {Void <SomeClass>b__0()}}
Bleh(); // `action` still == {Method = {Void <SomeClass>b__0()}}
}
}
Would the lambda ever return a new instance, or is it guaranteed to always be the same?
I see Skeet jumped in while I was answering, so I won't belabor that point. One thing I would suggest, to better understand how you are using things, is to get familiar with reverse engineering tools and IL. Take the code sample(s) in question and reverse engineer to IL. It will give you a great amount of information on how the code is working.
Based on your question here and your comment to Jon's answer I think you are confusing multiple things. To make sure it is clear:
So if you have something like:
then every time M is called, you get the same instance of the delegate because the compiler is smart and generates
If you have
then the compiler generates
You get a new delegate every time, with the same method.
The compiler is permitted to (but in fact does not at this time) generate
In that case you would always get the same delegate instance if possible, and every delegate would be backed by the same method.
If you have
Then in practice the compiler generates this as
However the compiler is permitted to detect that the two lambdas are identical and generate
Is that now clear?
No guarantees.
A quick demo:
Call this twice, do a
ReferenceEquals(a,b)
, and you'll gettrue
Call this twice, do a
ReferenceEquals(a,b)
, and you'll getfalse
Good question. I don't have an "academic answer," more of a practical answer: I could see a compiler optimizing the binary to use the same instance, but I wouldn't ever write code that assumes it's "guaranteed" to be the same instance.
I upvoted you at least, so hopefully someone can give you the academic answer you're looking for.
It's not guaranteed either way.
From what I remember of the current MS implementation:
EDIT: The relevant text of the C# 4 spec is in section 6.5.1: