C # 4 "dynamisch" in Ausdrucksbäumen

c# c#-4.0 dynamic expression-trees

Frage

Ich versuche herauszufinden, wie man alle Teile zusammenfügt, und würde ein konkretes Quellcode-Beispiel für einen einfachen Fall zu schätzen wissen.

Betrachten Sie den folgenden C # -Code:

Func<int, int, int> f = (x, y) => x + y;

Ich kann zur Laufzeit eine äquivalente Funktion unter Verwendung von Ausdrucksbäumen wie folgt erzeugen:

var x = Expression.Parameter(typeof(int), "x");
var y = Expression.Parameter(typeof(int), "y");
Func<int, int, int> f =
    Expression.Lambda<Func<int, int, int>>(
        Expression.Add(x, y),
        new[] { x, y }
    ).Compile();

Nun gegeben das folgende Lambda:

Func<dynamic, dynamic, dynamic> f = (x, y) => x + y;

Wie würde ich das Äquivalent mithilfe von Ausdrucksbäumen (und vermutlich Expression.Dynamic ) erzeugen?

Akzeptierte Antwort

Sie können eine Ausdrucksstruktur erstellen, die einen dynamischen C # -Ergänzungsausdruck darstellt, indem Sie den CallSiteBinder für einen dynamischen C # -Expressionsausdruck an Expression.Dynamic übergeben. Sie können den Code zum Erstellen der Sammelmappe ermitteln, indem Sie Reflector für den ursprünglichen dynamischen Ausdruck ausführen. Ihr Beispiel würde etwa so aussehen:

var x = Expression.Parameter(typeof(object), "x");
var y = Expression.Parameter(typeof(object), "y");
var binder = Binder.BinaryOperation(
    CSharpBinderFlags.None, ExpressionType.Add, typeof(Program),
    new CSharpArgumentInfo[] { 
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null), 
        CSharpArgumentInfo.Create(CSharpArgumentInfoFlags.None, null)});
Func<dynamic, dynamic, dynamic> f =
    Expression.Lambda<Func<object, object, object>>(
        Expression.Dynamic(binder, typeof(object), x, y),
        new[] { x, y }
    ).Compile();

Beliebte Antwort

Sie können das nicht tun, weil eine Ausdrucksbaumstruktur "keine dynamische Operation enthalten darf".

Folgendes wird nicht kompiliert, zum Beispiel wegen der Operation +, und Sie versuchen, eine Ausdrucksbaumstruktur zu erstellen, die diese Regel verletzt:

 Expression<Func<dynamic, dynamic, dynamic>> f = (x, y) => x + y;

Wenn du keine Add-Operation machst, könntest du damit durchkommen.

Siehe So erstellen Sie einen Ausdruck <Func <dynamisch, dynamisch >> - Oder ist es ein Fehler? für mehr Informationen.

Bearbeiten:

Dies ist so nah wie möglich, indem ich meine eigene Add-Methode definiere, die dynamische Parameter verwendet und ein dynamisches Ergebnis zurückgibt.

    class Program
{
    static void Main(string[] args)
    {

        var x = Expression.Parameter(typeof(object), "x");
        var y = Expression.Parameter(typeof(object), "y");
         Func<dynamic, dynamic, dynamic> f =
             Expression.Lambda<Func<dynamic, dynamic, dynamic>>(
                 Expression.Call(typeof(Program), "Add", null, x, y),
                 new[] { x, y }
             ).Compile();

       Console.WriteLine(f(5, 2));
       Console.ReadKey();
    }

    public static dynamic Add(dynamic x, dynamic y)
    {
        return x + y;
    }
}


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