У меня была часть кода, которая принимает лямбда-выражения во время выполнения, которые я затем могу скомпилировать и вызвать.
Something thing;
Expression<Action<Something>> expression = (c => c.DoWork());
Delegate del = expression.Compile();
del.DynamicInvoke(thing);
Чтобы сэкономить время выполнения, я сохранил эти скомпилированные делегаты в кеше, Dictionary<String, Delegate>
, ключом которого является строка лямбда-выражения.
cache.Add("(Something)c => c.DoWork()", del);
Для точно таких же звонков все работало нормально. Однако я понял, что могу получить эквивалентные лямбда-выражения, такие как «d => d.DoWork()», для которых я действительно должен использовать тот же делегат, а я этого не сделал.
Это заставило меня задуматься, есть ли чистый способ (читай "без использования String.Replace", я уже сделал это как временное исправление) для замены элементов в лямбда-выражении, например, замена их на arg0
, чтобы оба
(c => c.DoWork())
и (d => d.DoWork())
преобразуются и сравниваются как (arg0 => arg0.DoWork())
с помощью чего-то функционально похожего на вставку Expression.Parameter(Type, Name) в лямбду.
Это возможно ? (Ответы могут включать C# 4.0)
(f,g) => f.Method(g)
, а у меня будут типы f и g. На самом деле ключ довольно приземлен и не высечен на камне, любой подходящий способ представить эквивалентность между двумя лямбда-выражениями кроме((T)arg0,(V)arg1) => arg0.Method(arg1)
может помочь в качестве ключа. - person Dynami Le Savard   schedule 20.01.2010