2017-06-02 55 views
2

我想延長的表達式(Expression<Func<TModel, TProperty>>):C#擴展表達式

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項目)中使用驗證。

ValidationMessageFor方法中的htmlAttributes方法不起作用,並且使用沒有表達式的模型!

回答

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)。