成员表达式到成员表达式[]

发布于 2024-10-08 08:07:04 字数 1867 浏览 8 评论 0 原文

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

因此,我尝试创建的方法的签名是:

MemberExpression[] GetMemberExpressionArray(Expression> instanceExpression, Expression>nestedMemberExpression)< /code>

其中 nestedMemberExpression 将被假定采用

parent =>; 形式的参数Parent.ChildProperty.GrandChildProperty

和结果数组表示从 parentChildProperty 以及从 ChildProperty 的值到 的 MemberAccess >GrandChildProperty

我已经使用以下扩展方法返回了最后一个 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 并且该反射应该会损害性能。

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

对于如何以最佳性能和可靠性完成此任务(以及一般情况下此类任务)的任何建议,我将不胜感激。

The objective is to get an array of MemberExpressions from two LambdaExpressions. The first is convertible to a MethodCallExpression that returns the instance of an object (Expression<Func<T>>). The second Lambda expression would take the result of the compiled first expression and return a nested member (Expression<Func<T,TMember>>). We can assume that the second Lambda expression will only make calls to nested properties, but may do several of these calls.

So, the signature of the method I am trying to create is :

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

where nestedMemberExpression will be assumed to take an argument of the form

parent => parent.ChildProperty.GrandChildProperty

and the resulting array represents the MemberAccess from parent to ChildProperty and from the value of ChildProperty to GrandChildProperty.

I have already returned the last MemberExpression using the following extension method.

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;
} 

Now, I know there are several ways to accomplish this. The most immediately intuitive to me would be to loop through the .Expression property to get the first expression and capture references to each MemberExpression along the way. This may be the best way to do it, but it may not. I am not extraordinarily familiar with the performance costs I get from using expressions like this. I know a MemberExpression has a MemberInfo and that reflection is supposed to hurt performance.

I've tried to search for information on expressions, but my resources have been very limited in what I've found.

I would appreciate any advice on how to accomplish this task (and this type of task, in general) with optimal performance and reliability.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

万劫不复 2024-10-15 08:07:04

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

您可能必须覆盖 VisitMember 方法以便:

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

我想这看起来像:

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

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

I'm not sure why this has been tagged performance, but the easiest way I can think of to extract member-expressions from a tree is to subclass ExpressionVisitor. This should be much simpler than manually writing the logic to 'expand' different types of expressions and walk the tree.

You'll probably have to override the VisitMember method so that:

  1. Each member-expression is captured.
  2. Its children are visited.

I imagine that would look something like:

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

I'm slightly unclear about the remainder of your task; it appears like you want to rewrite parameter-expressions, in which case you might want to look at this answer from Marc Gravell.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文