Скомпилированное лямбда-выражение, приводящее к выделению новых делегатов, тогда как версия без выражения этого не делаеC#

Место общения программистов C#
Ответить
Anonymous
 Скомпилированное лямбда-выражение, приводящее к выделению новых делегатов, тогда как версия без выражения этого не делае

Сообщение Anonymous »

Это скомпилированное дерево выражений...

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

var param = Expression.Parameter(typeof(int));
var innerParam = Expression.Parameter(typeof(Action));
var inner = Expression.Lambda(innerParam.Type, Expression.Block(), "test", new[] { param });
var outer = Expression.Lambda(Expression.Block(new[] { innerParam }, Expression.Assign(innerParam, inner), Expression.Invoke(innerParam, param)), param).Compile();
Похоже, что это приводит к созданию нового делегата при каждом отдельном вызове внешнего - это заметно, если, например, установить точку останова в Delegate.CreateDelegateNoSecurityCheck.
Напротив, эквивалент этой функции, не основанный на выражениях

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

Action outer = x =>
{
Action innerParam = _ => { };
innerParam(x);
};
похоже, не делает этого; повторные вызовы внешнего не требуют выделения новых делегатов.
Я с трудом понимаю, почему. Это предназначено? Есть ли какой-нибудь изящный трюк для кэширования делегатов версии на основе выражений?

Для контекста: это возникло при использовании внешней библиотеки десериализации, которая, казалось, выделяла необоснованный объем памяти из-за создания делегата в нашем процессе. По сути, он делает нечто очень похожее — создает десериализаторы с помощью деревьев выражений и назначает делегатов локальным переменным для поддержки рекурсивной и циклической десериализации.

Подробнее здесь: https://stackoverflow.com/questions/787 ... s-non-expr
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

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