简体   繁体   中英

Get MemberInfo of child property from a MemberExpression

I am trying to get MemberInfo for a child property from a MemberExpression. I have found ways to get the full name of the nested type, but not a way to get the whole MemberInfo of the nested type. Here is a quick example of the scenario I am talking about:

Some simple models (the goal is to eventually get the MemberInfo of the Data property of the Child class)

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

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

The lambda expression

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

Code used to get the MemberInfo from the lambda expression.

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

This code works great if I were trying to get the ParentProperty of the Parent class, but when I try to get the MemberInfo of the Data property of the Child class, it does not work. I have seen a few StackOverflow questions posted on getting the full name of the child property, but nothing on getting the whole MemberInfo of it. Has anyone done this before or can help point me in the right direction?

You must be using Expression instead of just Func

In your code in the MemberAccess section you are checking if the member is from the parameter, in this case Parent. If you remove that check then you will get the member for Data

Change this section

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

To

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

I don't know why you had the guard for the parameter, if you need it in certain cases then you can create a different method or pass in a parameter.

The expression you get is MemberExpression, you can grab its Member property directly:

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

Output:

System.String Data
Int32 A

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM