2011-01-05 9 views
12

Wie ein ExpressionTree von FormExpression Baum Kopieren oder Konvertieren

Expression<Func<POCO1, bool>> exp = p => p.Age > 50; 

zu

Expression<Func<POCO2, bool>> exp2 = p => p.Age > 50; 

wo poco1 und POCO2 sind C# Objekte zu konvertieren, und beide haben Int32 Alte Eigenschaft

+0

Was möchten Sie tun? Ich meine, warum willst du es so kopieren? –

Antwort

15

gut, können Sie benutzerdefinierte Ausdruck Besucher machen, die Parameterreferenzen und Patch ersetzen Mitgliedszugriffsausdrücke

class Converter<TTo> 
{ 
    class ConversionVisitor : ExpressionVisitor 
    { 
     private readonly ParameterExpression newParameter; 
     private readonly ParameterExpression oldParameter; 

     public ConversionVisitor(ParameterExpression newParameter, ParameterExpression oldParameter) 
     { 
      this.newParameter = newParameter; 
      this.oldParameter = oldParameter; 
     } 

     protected override Expression VisitParameter(ParameterExpression node) 
     { 
      return newParameter; // replace all old param references with new ones 
     } 

     protected override Expression VisitMember(MemberExpression node) 
     { 
      if (node.Expression != oldParameter) // if instance is not old parameter - do nothing 
       return base.VisitMember(node); 

      var newObj = Visit(node.Expression); 
      var newMember = newParameter.Type.GetMember(node.Member.Name).First(); 
      return Expression.MakeMemberAccess(newObj, newMember); 
     } 
    } 

    public static Expression<Func<TTo, TR>> Convert<TFrom, TR>(
     Expression<Func<TFrom, TR>> e 
     ) 
    { 
     var oldParameter = e.Parameters[0]; 
     var newParameter = Expression.Parameter(typeof(TTo), oldParameter.Name); 
     var converter = new ConversionVisitor(newParameter, oldParameter); 
     var newBody = converter.Visit(e.Body); 
     return Expression.Lambda<Func<TTo, TR>>(newBody, newParameter); 
    } 
} 

class A 
{ 
    public int Value { get; set; } 
} 

class B 
{ 
    public int Value { get; set; } 
} 

Expression<Func<A, int>> f = x => x.Value; 
var f2 = Converter<B>.Convert(f); 
1

Rauen Schritte:

 
 
Get the expression Cast it to BinaryExpression 
Get the left operand Cast it to MemberExpression 
Get the Underlying Type that the property belong to 
Change it to your new type if you can. 
 

Th Der Typ, den Sie hier bekommen, ist eine Eigenschaft ohne Setter, wie ich vermutete.

Expression<Func<MainWindow, bool >> exp1 = o => this.ActualHeight>50; 
var type = ((MemberExpression)((BinaryExpression)exp1.Body).Left).Expression.Type; 

So müssen Sie einen neuen Ausdruck bauen

Hier wird die Art und Weise

manually build linq expression for x => x.Child == itemToCompare.Child

0

Idealerweise - Sie nicht. Erstellen Sie eine Schnittstelle, die die Age-Eigenschaft beschreibt, und erstellen Sie den Ausdruck so, dass er sich auf ,, bezieht. Wenn Sie die POCO-Typen nicht ändern können, verwenden Sie eine Sprache wie Go, wobei Schnittstellen implizit sind :-).

Verwandte Themen