c#扩展表达式

时间:2017-06-02 09:38:00

标签: c# asp.net-mvc expression

我想扩展一个表达式(Expression<Func<TModel, TProperty>>):

class CustomModel
{
    public BlobModel Blob { get; set; }

    public class BlobModel
    {
        public string SubBlob { get; set; }
    }
}


var expression = model => model.Blog;
var subBlobExpression = expression.???.SubBlob;

有可能吗? 目标是在shared partialview(ASP.NET MVC项目)中使用验证。

htmlAttributes方法中的ValidationMessageFor无法使用没有表达式的模型!

1 个答案:

答案 0 :(得分:0)

不清楚你到底想要什么以及你有什么限制,但是:

// Taken (with some cuts) from https://stackoverflow.com/a/32007349/613130

// A simple expression visitor to replace some nodes of an expression 
// with some other nodes. Can be used with anything, not only with
// ParameterExpression
public class SimpleExpressionReplacer : ExpressionVisitor
{
    public readonly Dictionary<Expression, Expression> Replaces;

    public SimpleExpressionReplacer(Expression from, Expression to)
    {
        Replaces = new Dictionary<Expression, Expression> { { from, to } };
    }

    public override Expression Visit(Expression node)
    {
        Expression to;

        if (node != null && Replaces.TryGetValue(node, out to))
        {
            return base.Visit(to);
        }

        return base.Visit(node);
    }
}

public static Expression<Func<T, TProp2>> ExtendExpression<T, TProp1, TProp2>(Expression<Func<T, TProp1>> exp1, Expression<Func<TProp1, TProp2>> exp2)
{
    Expression body3 = new SimpleExpressionReplacer(exp2.Parameters[0], exp1.Body).Visit(exp2.Body);
    Expression<Func<T, TProp2>> exp3 = Expression.Lambda<Func<T, TProp2>>(body3, exp1.Parameters);
    return exp3;
}

使用它像:

Expression<Func<CustomModel, CustomModel.BlobModel>> expression = model => model.Blob;
var exp2 = ExtendExpression(expression, x => x.SubBlob);

我使用表达式替换器(SimpleExpressionReplacer)将两个表达式“expressionx => x.SubBlob”合并在一起。