Was macht Expression.Reduce ()?

.net c# expression-trees lambda

Frage

Ich arbeite jetzt seit einigen Tagen mit Expression-Bäumen und bin gespannt, was Expression.Reduce () tut. Die msdn-Dokumentation ist nicht sehr hilfreich, da sie nur besagt, dass sie den Ausdruck "reduziert". Nur für den Fall, ich versuchte ein Beispiel (siehe unten), um zu überprüfen, ob diese Methode mathematische Reduktion enthalten, aber das scheint nicht der Fall zu sein.

Weiß jemand, was diese Methode macht und ist es möglich, ein schnelles Beispiel zu geben, das diese Aktion zeigt? Irgendwelche guten Ressourcen da draußen?

static void Main(string[] args)
{
    Expression<Func<double, double>> func = x => (x + x + x) + Math.Exp(x + x + x);
    Console.WriteLine(func);
    Expression r_func = func.Reduce();
    Console.WriteLine(r_func); // This prints out the same as Console.WriteLine(func)
}

Akzeptierte Antwort

Das Dokument, das Sie betrachten müssen, ist "expr-tree-spec.doc" hier: http://dlr.codeplex.com/wikipage?title=Docs%20and%20specs&referringTitle=Documentation

Dies ist die Spezifikation für die Ausdrucksbäume. Lesen Sie die Abschnitte "2.2 Reducible Nodes" und "4.3.5 Reduce Method".

Grundsätzlich ist diese Methode für Personen gedacht, die ihre dynamischen Sprachen in .NET implementieren oder portieren. Damit können sie eigene Knoten erstellen, die auf Standard-Ausdrucksbaumknoten "reduziert" werden können und kompiliert werden können. Es gibt einige "reduzierbare" Knoten in der Ausdrucksbaum-API, aber ich weiß nicht, ob Sie irgendwelche praktischen Beispiele bekommen können (da alle Standard-Ausdrucksknoten sowieso kompilieren, ist es für den Endanwender wahrscheinlich egal, ob sie "reduziert" sind) "Hinter den Kulissen oder nicht".

Ja, die MSDN-Dokumentation ist in diesem Bereich sehr einfach, da die Hauptquelle für Informationen und Dokumente für Sprachimplementierer http://dlr.codeplex.com/


Beliebte Antwort

Mit ein wenig Auseinanderbauen fand ich , dass Expression.CanReduce immer reutrns false und Expression.Reduce () gibt immer this . Es gibt jedoch einige Arten, die beide überschreiben. LambdaExpression erbt die Standardimplementierungen, was erklärt, warum die Ausdrücke, die bisher versucht wurden, nicht funktionieren.

Einer der Typen, die Reduce () überschreiben, ist MemberInitExpression, was mich zu dem folgenden erfolgreichen Experiment führte:

class ReduceFinder : ExpressionVisitor {
    public override Expression Visit(Expression node) {
        if (node != null && node.CanReduce) {
            var reduced = node.Reduce();
            Console.WriteLine("Found expression to reduce!");
            Console.WriteLine("Before: {0}: {1}", node.GetType().Name, node);
            Console.WriteLine("After: {0}: {1}", reduced.GetType().Name, reduced);
        }
        return base.Visit(node);
    }
}

class Foo {
    public int x;
    public int y;
}

static class Program {
    static void Main() {
        Expression<Func<int, Foo>> expr = z => new Foo { x = (z + 1), y = (z + 1) };
        new ReduceFinder().Visit(expr);
    }
}

Ausgabe:

class ReduceFinder : ExpressionVisitor {
    public override Expression Visit(Expression node) {
        if (node != null && node.CanReduce) {
            var reduced = node.Reduce();
            Console.WriteLine("Found expression to reduce!");
            Console.WriteLine("Before: {0}: {1}", node.GetType().Name, node);
            Console.WriteLine("After: {0}: {1}", reduced.GetType().Name, reduced);
        }
        return base.Visit(node);
    }
}

class Foo {
    public int x;
    public int y;
}

static class Program {
    static void Main() {
        Expression<Func<int, Foo>> expr = z => new Foo { x = (z + 1), y = (z + 1) };
        new ReduceFinder().Visit(expr);
    }
}



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