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
To
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.