Что значит фраза "делегат кэшируется" в этом контексте (и вообще, что такое "кэшированный делегат и для чего он):
"В случае вызова SomeMethod(OtherMethod) — будет всегда создаваться делегат.
В случае вызова SomeMethod(x => OtherMethod(x)) — делегат будет кешироваться."?
Контекст отсюда
UPD
Между первым вызовом и вторым есть разница в MSIL'е, а именно такой код:
static void SomeMethod(Func
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
}
Будет преобразован примерно в следующий:
static void Main()
{
SomeMethod(new Func
Но как видно, компилятор на 3 вызов создал и инициализировал новую "кэшированную" переменную, а не использовал старую
Ответ
Обсуждаемая тема — особенность кодогенерации текущей версии майкрософтовского фреймворка .NET.
Обсуждаемый код таков:
class Program
{
static void SomeMethod(Func
static void Main(string[] args)
{
SomeMethod(OtherMethod); // 1
SomeMethod(x => OtherMethod(x)); // 2
}
}
При этом на текущий момент вызов
SomeMethod(OtherMethod); // 1
компилируется в аналог такого:
SomeMethod(new Func
(дело в том, что OtherMethod — не делегат, а метод, вот компилятор и любезно подставил создание делегата). А вызов
SomeMethod(x => OtherMethod(x)); // 2
— в аналог такого (по поводу LambdaClass смотрите здесь):
Func
То есть значение делегата (Func
Но я бы не придавал этому факту большого значения: кодогенерация даже в Microsoft .NET меняется со временем (вот недавние изменения в кодогенерации лямбд, а вот недоумение команды, которая рассчитывала в своём коде на недокументированные особенности), а уж кодогенерация в других имплементациях имеет право отличаться и подавно.
Комментариев нет:
Отправить комментарий