Is there a particular reason LinqKit's expander can't pick up Expressions from fields?

依然范特西╮ 提交于 2019-11-29 21:06:43

I downloaded sourcecode and tried to analyse it. ExpressionExpander does not allow to reference expressions that are stored in variables other than constant. It expects expression that Invoke method is being called upon to reference to object represented by ConstantExpression, not another MemberExpression.

So we cannot provide our reusable expression as reference to any member of the class (even public fields, not properties). Nesting member access (like object.member1.member2 ... etc) is not supported too.

But this can be fixed by traversing initial expression and recusrsively extracting subfields values.

I have replaced TransformExpr method code of ExpressionExpander class to

var lambda = Expression.Lambda(input);
object value = lambda.Compile().DynamicInvoke();

if (value is Expression)
    return Visit((Expression)value);
else
    return input;

and it works now.

In this solution everything I mentioned before (recursively traversing tree) is done for us by ExpressionTree compiler :)

Yankes

I created improved version of Mic answer:

if (input == null)
    return input;

var field = input.Member as FieldInfo;
var prope = input.Member as PropertyInfo;
if ((field != null && field.FieldType.IsSubclassOf(typeof(Expression))) ||
    (prope != null && prope.PropertyType.IsSubclassOf(typeof(Expression))))
    return Visit(Expression.Lambda<Func<Expression>>(input).Compile()());

return input;

Main advantage is removal DynamicInvoke that have big overhead and calling Invoke only when I really need it.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!