Expression Tree- und Compile-Methode

c# expression-trees lambda

Frage

Dies ist alles über die Compile Methode des Expression . Es tut mir leid, naiv zu sein, da ich ein späterer Gast bin. Ich habe über das Erstellen von Ausdruck gelesen, um die dynamische Änderung von ausführbarem Code zu ermöglichen. Und es macht Sinn für mich, wenn ich einen Lambda-Ausdruck von einem gegebenen Ausdrucksbaum aussenden möchte, so lange wie für die variierenden Eingaben / Umgebung (sagen wir für verschiedene Werte für jeden gegebenen Konstanten / Parameter / Element-Ausdruck). Ich nehme an, es wäre ideal, wenn ich Lambda, die aus einem Ausdrucksbaum erzeugt / kompiliert werden, cachen (wiederverwenden) könnte, vorausgesetzt, es gibt keine Änderung in der Umgebung.

Frage : Gibt CLR immer einen Lambda-Ausdruck aus, auch wenn ich keine Veränderung in der Umgebung habe? Wenn ja, was ist das Beste, wenn man die Expression von Lambda nicht kompiliert, wenn sich die Umgebung nicht ändert?

Akzeptierte Antwort

Lambda-Ausdrücke stellen nur eine Möglichkeit dar, ein Stück Code darzustellen: Rufen Sie das auf, rufen Sie dieses Argument auf, vergleichen Sie diese Argumente, geben Sie etwas zurück, usw. Fast genauso wie Sie es aus dem Code-Editor machen, oder JIT von IL.

Compile gibt einen Delegaten von einem bestimmten Lambda-Ausdruck aus. Sobald Sie Lambda in den Delegaten übersetzt haben, bleibt der Delegat unverändert (das Lambda bleibt ebenfalls unverändert, da es unveränderlich ist).

Dies bedeutet nicht, dass der Delegat keine Argumente akzeptieren oder irgendeine Methode eines Objekts aufrufen kann. Das bedeutet nur, dass sich die IL des Delegierten nicht ändert. Und ja, Sie können die kompilierte Delegateninstanz zwischenspeichern.


Beliebte Antwort

CLR speichert keine Lambda-Ausdrücke, Compile() jedes Mal einen neuen Delegaten zurück.

Aber es sollte einfach sein, über so etwas zu cachen:

public Func<T> Get<T>(Expression<Func<T>> expression)
{
    string key = expression.Body.ToString();

    Func<T> result;
    if (!_cache.TryGetValue(key, out result)) {
        result = expression.Compile();
        _cache.Add(key, result);
    }

    return result;
}


Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow