Изменения в поведении делегированного кэширования в RoslynC#

Место общения программистов C#
Anonymous
Изменения в поведении делегированного кэширования в Roslyn

Сообщение Anonymous »

Учитывая следующий код:

Код: Выделить всё

public class C
{
public void M()
{
var x = 5;
Action action = y => Console.WriteLine(y);
}
}
Использование VS2013, .NET 4.5. Глядя на декомпилированный код, мы видим, что компилятор кэширует делегат на месте вызова:

Код: Выделить всё

public class C
{
[CompilerGenerated]
private static Action CS$9__CachedAnonymousMethodDelegate1;
public void M()
{
if (C.CS$9__CachedAnonymousMethodDelegate1 == null)
{
C.CS$9__CachedAnonymousMethodDelegate1 = new Action(C.b__0);
}
Action arg_1D_0 = C.CS$9__CachedAnonymousMethodDelegate1;
}
[CompilerGenerated]
private static void b__0(int y)
{
Console.WriteLine(y);
}
}
Просмотр того же кода, декомпилированного в Roslyn (с использованием TryRoslyn), дает следующий результат:

Код: Выделить всё

public class C
{
[CompilerGenerated]
private sealed class c__DisplayClass0
{
public static readonly C.c__DisplayClass0 CS$9__inst;
public static Action CS$9__CachedAnonymousMethodDelegate2;
static c__DisplayClass0()
{
// Note: this type is marked as 'beforefieldinit'.
C.c__DisplayClass0.CS$9__inst = new C.c__DisplayClass0();
}
internal void b__1(int y)
{
Console.WriteLine(y);
}
}
public void M()
{
Action arg_22_0;
if (arg_22_0 = C.c__DisplayClass0.CS$9__CachedAnonymousMethodDelegate2 == null)
{
C.c__DisplayClass0.CS$9__CachedAnonymousMethodDelegate2 =
new Action(C.c__DisplayClass0.CS$9__inst.b__1);
}
}
}
Теперь мы видим, что делегат теперь перемещается в частный класс внутри C, аналогичное поведение, которое мы привыкли видеть при закрытии переменная/поле экземпляра (замыкание).

Я знаю, это деталь реализации, которая может быть изменена в любой момент времени.

Тем не менее мне интересно, каковы преимущества переноса делегата в новый класс и его кэширования там по сравнению с простым кэшированием на месте вызова?

Изменить:

Эта проблема говорит о том же поведении, что и здесь.

Подробнее здесь: https://stackoverflow.com/questions/308 ... -in-roslyn

Вернуться в «C#»