Кэшировать делегат скомпилированного Dynamic Linq Func <> * без * params? - PullRequest
3 голосов
/ 27 июля 2010

Я использую метод Dynamic.ParseLambda из библиотеки Dynamic LINQ для создания выражений, компилирования каждого в Func <> и кэширования каждого в словаре:

// parse some dynamic expression using this ParseLambda sig:
Expression<Func<TArgument,TResult>> funcExpr = 
 System.Linq.Dynamic.ParseLambda<TArgument, TResult>(
  expressionString, // string for dyn lambda expression
  parameters);  // object[] params

// then compile & cache the output of this as a delegate:
Func<TArgument,TResult> func = funcExpr.Compile(); //<-cache this

// then to execute, use:
return func(entityInstance);

Проблема в том, что это заставляет меня кэшировать отдельный экземпляр делегата для каждого отдельного набора значений параметров. Это кажется расточительным; все накладные расходы с Dynamic LINQ находятся в разборе и компиляции; после создания делегаты имеют почти прямое кодирование лямбд в исполнении. Есть ли способ переместить параметры за пределы выражения, чтобы я мог передавать различные значения общему кэшированному делегату при его вызове (а не при создании)?

// e.g. with params...
return func(entityInstance,parameters);

// or if params are the issue, multiple signatures are ok:
return func(entityInstance, intValue, stringValue);

Я не вижу никаких сигнатур без параметров .ParseLambda или .Compile в System.Linq.Dynamic, так что мои надежды не высоки. Кто-нибудь знает быстрый способ достичь этого?

Спасибо!

1 Ответ

3 голосов
/ 27 июля 2010

Здесь есть хитрость, которую я использовал раньше;вы делаете что-то вроде Expression<Func<object[], object>>, и вставляете выборку по индексу и приводите внутри выражения.Тогда у вас будет столько параметров, сколько вы захотите, одна подпись и разумная производительность.Это делает , однако, делает написание лямбды немного обманчивым.

У меня нет своего старого кода для этого "на руку", но если мне нужно было его перепроектировать, япросто напишет что-нибудь типичное, например, следующее, а затем заглянет в отражатель, чтобы увидеть, что он использовал:

Expression<Func<object[], object>> func = arr => ((string)arr[0]) + (int)arr[1];

(в частности, обращая внимание на использование indexer , приведение с входов и преобразование на вывод )

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...