C#表达式 - 提取字符串名称(深)

时间:2013-09-07 16:27:51

标签: c# expression

我有以下功能,当我称之为GetPropertyName<Model>(x => x.Test)时返回“测试” 如何返回深度调用,例如:User.UserName 我想在User.UserName

之后看到GetPropertyName<Model>(x => x.User.FullName)

由于

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

修改1

这是我的课程:

public class Place : BaseEntity
{
     public virtual User UserManager { get; set; }
}

public class User : BaseEntity
{
     public virtual string FullName { get; set; }
}

1 个答案:

答案 0 :(得分:1)

此方法遍历表达式中的节点,将节点强制转换为属性并将其添加到列表中。

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

如果您想获得这样的字符串:User.UserName,您可以这样做:

var props = GetProperties<Model>(m => m.User.Username);
var propNames = props.Select(p => p.Name);
string names = string.Join(".", propNames);