【问题标题】:MemberExpression to MemberExpression[]MemberExpression 到 MemberExpression[]
【发布时间】:2010-12-17 20:48:19
【问题描述】:

目标是从两个 LambdaExpressions 中获取 MemberExpressions 数组。第一个可转换为返回对象实例的 MethodCallExpression (Expression<Func<T>>)。第二个 Lambda 表达式将获取已编译的第一个表达式的结果并返回一个嵌套成员 (Expression<Func<T,TMember>>)。我们可以假设第二个 Lambda 表达式只会调用嵌套属性,但可能会调用其中的几个。

所以,我要创建的方法的签名是:

MemberExpression[] GetMemberExpressionArray<T,TValue>(Expression<Func<T>> instanceExpression, Expression<Func<T,TValue>> nestedMemberExpression)

其中nestedMemberExpression 将被假定为采用以下形式的参数

parent => parent.ChildProperty.GrandChildProperty

结果数组表示从parentChildProperty 以及从ChildPropertyGrandChildProperty 的值的MemberAccess。

我已经使用以下扩展方法返回了最后一个MemberExpression

public static MemberExpression GetMemberExpression<T, TValue>(Expression<Func<T, TValue>> expression)
{
    if (expression == null)
    {
        return null;
    }
    if (expression.Body is MemberExpression)
    {
        return (MemberExpression)expression.Body;
    }
    if (expression.Body is UnaryExpression)
    {
        var operand = ((UnaryExpression)expression.Body).Operand;
        if (operand is MemberExpression)
        {
            return (MemberExpression)operand;
        }
        if (operand is MethodCallExpression)
        {
            return ((MethodCallExpression)operand).Object as MemberExpression;
        }
    }
    return null;
} 

现在,我知道有几种方法可以做到这一点。对我来说最直观的方法是循环遍历.Expression 属性以获取第一个表达式并在此过程中捕获对每个 MemberExpression 的引用。这可能是最好的方法,但也可能不是。我对使用这样的表达式所带来的性能成本并不是特别熟悉。我知道 MemberExpression 有一个 MemberInfo 并且反射应该会损害性能。

我尝试搜索有关表达式的信息,但我找到的资源非常有限。

对于如何以最佳性能和可靠性完成此任务(通常是此类任务)的任何建议,我将不胜感激。

【问题讨论】:

    标签: linq performance reflection lambda linq-expressions


    【解决方案1】:

    我不确定为什么将其标记为 performance,但我能想到的从树中提取成员表达式的 最简单方法是子类化 @987654321 @。这应该比手动编写逻辑来“扩展”不同类型的表达式并遍历树要简单得多。

    您可能必须重写 VisitMember 方法,以便:

    1. 每个成员表达式都被捕获。
    2. 访问它的孩子。

    我想这看起来像:

    protected override Expression VisitMember(MemberExpression node)
    {
        _myListOfMemberExpressions.Add(node);
        return base.VisitMember(node);
    }
    

    我对你剩下的任务有点不清楚;看起来您想要重写 参数表达式,在这种情况下,您可能需要查看 Marc Gravell 的 this answer

    【讨论】:

      猜你喜欢
      • 2018-06-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-09
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多