Создать выражение из Func
У меня есть код Func<TCollection, T>
в моем коде. Я использую его для выбора определенных свойств.
При вызове другого метода мне нужно Expression<Func<TCollection, T>>
в качестве параметра.
Есть ли способ конвертировать (или создать из) Func<TCollection, T>
в Expression<Func<TCollection, T>>
?
Спасибо
Ответы
Ответ 1
Вы не можете воссоздать выражение на основе метода, поскольку выражение должно знать исходные утверждения, а не IL. Однако вы можете создать Expresson, который вызывает вызов метода для вашей функции, например:
Func<int> func = () => 1;
Expression<Func<int>> expression = Expression.Lambda<Func<int>>(Expression.Call(func.Method));
Обратите внимание, что такие системы, как EF, не могут работать с этим
Ответ 2
Пока вы можете просто создать дерево выражений, которое вызывает ваш делегат, вряд ли это будет полезно - потому что делегат будет в основном быть черным ящиком, насколько это касается кода, анализирующего дерево выражений. Предполагая, что вы пытаетесь использовать что-то вроде LINQ to SQL, анализатор запросов должен быть способен заглянуть в вашу логику, чтобы преобразовать его в SQL - и он не может этого сделать, если он достигнет простого делегата.
Вероятно, вы, вероятно, измените код, который возникает с делегатом, для создания дерева выражений.
Ответ 3
Вы не можете создать выражение из делегата (от Func<TCollection, T>
до Expression<Func<TCollection, T>>
), но вы можете сделать oposite.
То есть, преобразуйте a Expression<Func<TCollection, T>>
в Func<TCollection, T>
, скомпилировав его (.compile
).
Итак, если вам нужно обоим, вы можете использовать выражения в своих функциях, и в случае необходимости, скомпилировать их и выполнить их на предоставленном объекте коллекции.
Мы должны, конечно, отметить, что компиляция выражения происходит медленно.
Ответ 4
Вы можете сделать что-то вроде этого:
Func<object, string> func = a => a.ToString();
Expression<Func<object, string>> expr = a => func(a);
Но вы получите только выражение, содержащее вызов метода, к исходному Func. Вы не сможете проанализировать содержимое самого функционала.