Рихтер пишет, что такое выражение:
internal sealed class AClass {
public static void CallbackWithoutNewingADelegateObject() {
ThreadPool.QueueUserWorkItem( obj => Console.WriteLine(obj ), 5);
}
}
Разворачивается в такое:
internal sealed class AClass {
// Это закрытое поле создано для кэширования делегата
// Преимущество: CallbackWithoutNewingADelegateObject не будет
// создавать новый объект при каждом вызове
// Недостатки: кэшированные объекты недоступны для сборщика мусора
[CompilerGenerated]
private static WaitCallback <>9__CachedAnonymousMethodDelegate1;
public static void CallbackWithoutNewingADelegateObject() {
if (<>9__CachedAnonymousMethodDelegate1 == null) {
// При первом вызове делегат создается и кэшируется
<>9__CachedAnonymousMethodDelegate1 =
new WaitCallback(<CallbackWithoutNewingADelegateObject>b__0);
}
ThreadPool.QueueUserWorkItem(<>9__CachedAnonymousMethodDelegate1, 5);
}
[CompilerGenerated]
private static void <CallbackWithoutNewingADelegateObject>b__0(
Object obj) {
Console.WriteLine(obj);
}
}
А как будет выглядеть код, если используется несколько лябд?
Бдует кешироваться последний делегат?
То, во что компилируется код (т. наз. lowering: процесс упрощения кода, переписывания новых возможностей через старые), можно посмотреть на https://sharplab.io.
Вот такой пример:
using System;
using System.Threading;
internal sealed class AClass
{
public static void CallbackWithoutNewingADelegateObject()
{
ThreadPool.QueueUserWorkItem(obj => Console.WriteLine(obj), 5);
ThreadPool.QueueUserWorkItem(obj => Console.WriteLine(obj), 42);
}
}
(тут) показывает, что кешируются оба делегата, каждый в своей переменной.
using System;
using System.Diagnostics;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Security;
using System.Security.Permissions;
using System.Threading;
// атрибуты
internal sealed class AClass
{
[CompilerGenerated]
[Serializable]
private sealed class <>c
{
public static readonly AClass.<>c <>9 = new AClass.<>c();
public static WaitCallback <>9__0_0;
public static WaitCallback <>9__0_1;
internal void <CallbackWithoutNewingADelegateObject>b__0_0(object obj)
{
Console.WriteLine(obj);
}
internal void <CallbackWithoutNewingADelegateObject>b__0_1(object obj)
{
Console.WriteLine(obj);
}
}
public static void CallbackWithoutNewingADelegateObject()
{
WaitCallback arg_26_0;
if ((arg_26_0 = AClass.<>c.<>9__0_0) == null)
{
AClass.<>c.<>9__0_0 = (arg_26_0 = new WaitCallback(
AClass.<>c.<>9.<CallbackWithoutNewingADelegateObject>b__0_0));
}
ThreadPool.QueueUserWorkItem(arg_26_0, 5);
WaitCallback arg_52_0;
if ((arg_52_0 = AClass.<>c.<>9__0_1) == null)
{
AClass.<>c.<>9__0_1 = (arg_52_0 = new WaitCallback(
AClass.<>c.<>9.<CallbackWithoutNewingADelegateObject>b__0_1));
}
ThreadPool.QueueUserWorkItem(arg_52_0, 42);
}
}
С другой стороны, не забывайте о том, что lowering в большинстве случаев не стандаризирован, и может отличаться от версии к версии, если команда разработчиков компилятора посчитает другой вариант более предпочтительным. Поэтому не стоит опираться в разработке на тот или иной вариант компиляции вашего кода.
Недавний пример: ранее делегаты кешировались так, как в вашем коде (private static WaitCallback
), а теперь для него создаётся отдельный класс (private sealed class <>c
). Фреймворк Moq
, который исходил из старого варианта кодогенерации, отвалился.
Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
Никак не подберу правильную последовательность передачи параметровВылетает ошибка, что входная строка имела неверный формат
Доброго времени суток! Возникла следующая трудность, при передаче данных о пользователе, прошедшем аутентификацию в приложении ASPNET MVC на строну...
У Xamarin Forms для android проекта хочу разместить изображение по нажатию на кнопкуДля этого в MainPage