获取lambda表达式属性的字符串版本

时间:2012-06-08 09:08:27

标签: linq generics c#-4.0 expression

与问题How can I get property name strings used in a Func of T类似。

假设我有一个lambda表达式 像这样存储在名为“getter”的变量中

Expression<Func<Customer, string>> productNameSelector =
    customer => customer.Product.Name;

如何从中提取字符串“Product.Name”?

我现在用

修复它
var expression = productNameSelector.ToString();
var token = expression.Substring(expression.IndexOf('.') + 1);

但我想找到一种更加坚实的方式; - )

2 个答案:

答案 0 :(得分:2)

表达式的表达式树如下所示:

           .
          / \
         .   Name
        / \
customer   Product

如您所见,没有代表Product.Name的节点。但是您可以使用递归并自己构建字符串:

public static string GetPropertyPath(LambdaExpression expression)
{
    return GetPropertyPathInternal(expression.Body);
}

private static string GetPropertyPathInternal(Expression expression)
{
    // the node represents parameter of the expression; we're ignoring it
    if (expression.NodeType == ExpressionType.Parameter)
        return null;

    // the node is a member access; use recursion to get the left part
    // and then append the right part to it
    if (expression.NodeType == ExpressionType.MemberAccess)
    {
        var memberExpression = (MemberExpression)expression;

        string left = GetPropertyPathInternal(memberExpression.Expression);
        string right = memberExpression.Member.Name;

        if (left == null)
            return right;

        return string.Format("{0}.{1}", left, right);
    }

    throw new InvalidOperationException(
        string.Format("Unknown expression type {0}.", expression.NodeType));
}

答案 1 :(得分:1)

如果你有一个Expression,你可以使用ToString方法来提取字符串表示:

Expression<Func<Customer, string>> productNameSelector = 
    customer => customer.Product.Name;

var expression = productNameSelector.ToString();
var token = expression.Substring(expression.IndexOf('.') + 1);