Исходя из вашего вопроса здесь и вашего комментария к ответу Джона, я думаю, что вы путаете несколько вещей. Чтобы убедиться, что это ясно:
- Метод , который поддерживает делегат для данной лямбды, всегда одинаков.
- Метод , который поддерживает делегат для "одной и той же" лямбды, которая встречается в лексическом смысле дважды, - это , допускается, чтобы был таким же, но на практике не то же самое в нашей реализации.
- Экземпляр делегата , который создается для данной лямбды, может или не может быть одинаковым, в зависимости от того, насколько умен его компилятор в отношении кеширования.
Так что если у вас есть что-то вроде:
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;
Однако компилятору разрешено определять, что две лямбды идентичны, и генерировать
static void MyAction1() {}
static Action ActionCache1 = null;
...
if (ActionCache1 == null) ActionCache1 = new Action(MyAction1);
Action a1 = ActionCache1;
Action a2 = ActionCache1;
Теперь понятно?