Создать выражение из 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. Вы не сможете проанализировать содержимое самого функционала.