使用表达式动态评估属性字符串

时间:2013-05-14 13:34:34

标签: c# lambda

如何构建一个能够实现以下目标的表达式:

public object Eval(object rootObj, string propertyString)

例如:Eval(person, "Address.ZipCode") => return person.Address.ZipCode

Expression.PropertyOrField不起作用,因为我没有每个中间属性的类型。我想避免在脚本库上创建依赖。

我想尝试使用表达式,因为它允许我存储这些表达式树的缓存,因为它们将被执行多次。我知道可以通过反射迭代或递归地执行此操作。

2 个答案:

答案 0 :(得分:10)

听起来你正在寻找这样的东西:

public object Eval(object root, string propertyString)
{
    var propertyNames = propertyString.Split('.');
    foreach(var prop in propertyNames)
    {
        var property = root.GetType().GetProperty(prop);
        if (property == null)
        {
            throw new Exception(...);
        }

        root = property.GetValue(root, null);
    }

    return root;
}

要创建Expression,请使用此选项:

public Expression Eval(object root, string propertyString)
{
    var propertyNames = propertyString.Split('.');
    ParameterExpression param = Expression.Parameter(root.GetType, "_");
    Expression property = param;
    foreach(var prop in propertyName)
    {
        property = Expression.PropertyOrField(property, prop);
    }

    return Expression.Lambda(property, param);
}

答案 1 :(得分:3)

以下是p.s.w.g代码的递归版本,与Expressions一起使用。

public Expression Eval(Expression expression, string property)
{
    var split = property.Split('.');
    if (split.Length == 1)
    {
        return Expression.PropertyOrField(expression, property);
    }
    else
    {
        return Eval(Expression.PropertyOrField(expression, split[0]), property.Replace(split[0] + ".", ""));
    }
}