Что значит фраза "делегат кэшируется" в этом контексте (и вообще, что такое "кэшированный делегат и для чего он):
"В случае вызова SomeMethod(OtherMethod)
— будет всегда создаваться делегат.
В случае вызова SomeMethod(x => OtherMethod(x))
— делегат будет кешироваться."?
Контекст отсюда
UPD
Между первым вызовом и вторым есть разница в MSIL
'е, а именно такой код:
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
}
Будет преобразован примерно в следующий:
static void Main()
{
SomeMethod(new Func<int, int>(OtherMethod));
if (C.foo != null)
SomeMethod(C.foo)
else
{
C.foo = new Func<int, int>(c, C.b)
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);
}
}
Но как видно, компилятор на 3 вызов создал и инициализировал новую "кэшированную" переменную, а не использовал старую
Обсуждаемая тема — особенность кодогенерации текущей версии майкрософтовского фреймворка .NET.
Обсуждаемый код таков:
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
}
}
При этом на текущий момент вызов
SomeMethod(OtherMethod); // 1
компилируется в аналог такого:
SomeMethod(new Func<int, int>(Program.OtherMethod));
(дело в том, что OtherMethod
— не делегат, а метод, вот компилятор и любезно подставил создание делегата). А вызов
SomeMethod(x => OtherMethod(x)); // 2
— в аналог такого (по поводу LambdaClass
смотрите здесь):
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);
То есть значение делегата (Func<int, int>
) и вправду кешируется.
Но я бы не придавал этому факту большого значения: кодогенерация даже в Microsoft .NET меняется со временем (вот недавние изменения в кодогенерации лямбд, а вот недоумение команды, которая рассчитывала в своём коде на недокументированные особенности), а уж кодогенерация в других имплементациях имеет право отличаться и подавно.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
Стандартный стиль не вписывается в мой дизайн, а вся валидация идет через MessageboxShow("Сообщение")
есть список lisview с кнопками внутрикак можно получить элемент списка и объект данных, кликнув по какой-либо кнопке внутри него ?
Есть некоторая кнопка, которая создана от класса UserControl(то есть является не стандартной)И мне нужно, что бы когда свойство этой кнопки IsEnabled...