【问题标题】:Get MemberInfo of child property from a MemberExpression从 MemberExpression 获取子属性的 MemberInfo
【发布时间】:2014-11-09 01:29:43
【问题描述】:

我正在尝试从 MemberExpression 获取子属性的 MemberInfo。我找到了获取嵌套类型全名的方法,但没有找到获取嵌套类型的整个 MemberInfo 的方法。这是我正在谈论的场景的一个简单示例:

一些简单的模型(目标是最终得到Child类的Data属性的MemberInfo)

public class Parent
{
    public int ParentProperty { get; set; }
    public Child Child { get; set; }
}

public class Child
{
    public string Data { get; set; }
}

lambda 表达式

Expression<Func<Parent,string>> func = new Func<Parent, string>(p =>
{
    return p.Child.Data;
});

用于从 lambda 表达式获取 MemberInfo 的代码。

internal static MemberInfo FindMemberInfoFromLambda(LambdaExpression lambda)
    {
        var expression = (Expression) lambda;
        var flag = false;

        while (!flag)
        {
            switch (expression.NodeType)
            {
                case ExpressionType.Convert:
                    expression = ((UnaryExpression) expression).Operand;
                    continue;
                case ExpressionType.Lambda:
                    expression = ((LambdaExpression) expression).Body;
                    continue;
                case ExpressionType.MemberAccess:
                    var memberExpression = (MemberExpression) expression;
                    if (memberExpression.Expression.NodeType == ExpressionType.Parameter ||
                        memberExpression.Expression.NodeType == ExpressionType.Convert)
                        return memberExpression.Member;
                    throw new Exception();
                default:
                    flag = true;
                    continue;
            }
        }
        throw new Exception();
    }

如果我尝试获取 Parent 类的 ParentProperty,此代码效果很好,但是当我尝试获取 Child 类的 Data 属性的 MemberInfo 时,它不起作用。我已经看到了一些关于获取子属性全名的 StackOverflow 问题,但没有关于获取它的整个 MemberInfo 的内容。有没有人这样做过或者可以帮助我指出正确的方向?

【问题讨论】:

  • 请展示一个好的、简洁、完整的代码示例。除其他外,它显示了如何从委托类型 Func&lt;Parent, string&gt;MemberExpression 的实例。见stackoverflow.com/help/mcve
  • 更新了代码示例,展示了我将如何获取 lambda 表达式并从中获取 MemberType

标签: c# lambda expression-trees func memberinfo


【解决方案1】:

你得到的表达式是MemberExpression,你可以直接获取它的Member属性:

class Program
{
    class Parent
    {
        public int A { get; set; }
        public Child Child { get; set; }
    }

    class Child
    {
        public string Data { get; set; }
    }

    public static MemberInfo GetMemberInfo(LambdaExpression exp)
    {
        var body = exp.Body as MemberExpression;
        return body.Member;
    }

    static void Main(string[] args)
    {
        Expression<Func<Parent, string>> func1 = p => p.Child.Data;
        Console.WriteLine(GetMemberInfo(func1));
        Expression<Func<Parent, int>> func2 = p => p.A;
        Console.WriteLine(GetMemberInfo(func2));
    }
}

输出:

System.String Data
Int32 A

【讨论】:

    【解决方案2】:

    您必须使用 Expression 而不仅仅是 Func

    在 MemberAccess 部分的代码中,您正在检查成员是否来自参数,在本例中为 Parent。如果您删除该检查,那么您将获得数据成员

    更改此部分

    case ExpressionType.MemberAccess:
        var memberExpression = (MemberExpression) expression;
        if (memberExpression.Expression.NodeType == ExpressionType.Parameter ||
            memberExpression.Expression.NodeType == ExpressionType.Convert)
            return memberExpression.Member;
        throw new Exception();
    

    case ExpressionType.MemberAccess:
        var memberExpression = (MemberExpression) expression;
        return memberExpression.Member;
    

    我不知道为什么你有参数的保护,如果你在某些情况下需要它,那么你可以创建一个不同的方法或传入一个参数。

    【讨论】:

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