Reputation: 11165
I have the function bellow, returning "Test" when I call it GetPropertyName<Model>(x => x.Test)
.
How can I return deep call eg: User.UserName.
I want to see User.UserName
when I call it GetPropertyName<Model>(x => x.User.FullName)
Thanks
public static string GetPropertyName<T>(Expression<Func<T, object>> expression)
{
var body = expression.Body as MemberExpression;
if (body == null)
{
body = ((UnaryExpression)expression.Body).Operand as MemberExpression;
}
if (body != null)
{
return body.Member.Name;
}
return null;
}
Edit 1
this is my classes:
public class Place : BaseEntity
{
public virtual User UserManager { get; set; }
}
public class User : BaseEntity
{
public virtual string FullName { get; set; }
}
Upvotes: 0
Views: 268
Reputation: 68670
This method loops through the nodes in the expression, casts the node to a property and adds it to a list.
private IList<PropertyInfo> GetProperties<T>(Expression<Func<T, object>> fullExpression)
{
Expression expression;
switch (fullExpression.Body.NodeType)
{
case ExpressionType.Convert:
case ExpressionType.ConvertChecked:
var ue = fullExpression.Body as UnaryExpression;
expression = ((ue != null) ? ue.Operand : null) as MemberExpression;
break;
default:
expression = fullExpression.Body as MemberExpression;
break;
}
var props = new List<PropertyInfo>();
while(expression != null && expression.NodeType == ExpressionType.MemberAccess)
{
var memberExp = expression as MemberExpression;
if(memberExp.Member is FieldInfo)
throw InvalidExpressionException.FieldFound;
var prop = memberExp.Member as PropertyInfo;
props.Insert(0, prop);
expression = memberExp.Expression;
}
return props;
}
If you then want to get a string like this: User.UserName
, you can do it this way:
var props = GetProperties<Model>(m => m.User.Username);
var propNames = props.Select(p => p.Name);
string names = string.Join(".", propNames);
Upvotes: 2