根据您在此处提出的问题以及您对 Jon 的回答的评论,我认为您混淆了很多事情。为了确保清楚:
- 为给定 lambda 支持委托的方法始终相同。
- 支持在词法上出现两次的“相同”lambda 的委托的方法允许相同,但实际上不 em> 在我们的实现中也是如此。
- 为给定 lambda 创建的 委托实例 可能始终相同,也可能不同,具体取决于编译器缓存它的智能程度。
所以如果你有类似的东西:
for(i = 0; i < 10; ++i)
M( ()=>{} )
那么每次调用 M 时,你都会得到委托的相同的实例,因为编译器很聪明并且会生成
static void MyAction() {}
static Action DelegateCache = null;
...
for(i = 0; i < 10; ++i)
{
if (C.DelegateCache == null) C.DelegateCache = new Action ( C.MyAction )
M(C.DelegateCache);
}
如果你有
for(i = 0; i < 10; ++i)
M( ()=>{this.Bar();} )
然后编译器生成
void MyAction() { this.Bar(); }
...
for(i = 0; i < 10; ++i)
{
M(new Action(this.MyAction));
}
您每次都会使用相同的方法获得一个新的委托。
编译器被允许生成(但实际上此时并没有)
void MyAction() { this.Bar(); }
Action DelegateCache = null;
...
for(i = 0; i < 10; ++i)
{
if (this.DelegateCache == null) this.DelegateCache = new Action ( this.MyAction )
M(this.DelegateCache);
}
在这种情况下,如果可能,您将始终获得相同的委托实例,并且每个委托都将由相同的方法支持。
如果你有
Action a1 = ()=>{};
Action a2 = ()=>{};
然后在实践中编译器将其生成为
static void MyAction1() {}
static void MyAction2() {}
static Action ActionCache1 = null;
static Action ActionCache2 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
if (ActionCache2 == null) ActionCache2 = new Action(MyAction2);
Action a2 = ActionCache2;
但是编译器被允许检测到两个 lambda 是相同的并生成
static void MyAction1() {}
static Action ActionCache1 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
Action a2 = ActionCache1;
现在清楚了吗?