Ausdrucksbaum Kopieren oder konvertieren

c# dynamic-language-runtime expression-trees lambda

Frage

Wie man einen ExpressionTree der Form konvertiert

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

zu

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

POCO1 und POCO2 sind C # -Objekte, und beide haben Int32 Age-Eigenschaft

Akzeptierte Antwort

Nun, Sie können einen benutzerdefinierten Ausdruck-Besucher erstellen, der Parameterverweise und Zugriffszugriffs-Ausdrücke für Patch-Member ersetzt

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

Beliebte Antwort

Grobe 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.

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


 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.

Sie müssen also einen neuen Ausdruck erstellen

Hier ist der Weg

Erstellen Sie linq-Ausdruck manuell für x => x.Child == itemToCompare.Child




Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum