2016-04-18 7 views
1

Ich habe den folgenden Code:Wie den von Expression.Call() zurückgegebenen Wert einem ParameterExpression zuweisen?

var factory = Expression.Parameter(typeof(FooFactory)); 
var fooInstance = Expression.Variable(typeof(Foo)); 

var factoryCall = Expression.Call(factory, "Instantiate", new[] { typeof(Foo) }); 
Expression.Assign(fooInstance, factoryCall); 

List<Expression> expressions = new List<Expression>(); 
// TODO : add more expressions to do things on fooInstance ...// 

expressions.Add(fooInstance); //return fooInstance 
Expression finalExpr = Expression.Block(new[] { fooInstance }, expressions); 

Was es tun soll:

  1. Verwenden Fabrik als Parameter angegeben und Instantiate<T>() Methode nennen.
  2. Den zurückgegebenen Wert (eine foo-Instanz) in einer lokalen Variablen speichern.
  3. Dinge tun, auf diese lokale Variable
  4. Return die Instanz

Das Problem ist (in diesem Beispiel fehlt): Wenn ich kompilieren und rufen Sie den Ausdruck, Instantiate() nie aufgerufen. Der zurückgegebene Wert ist immer Null:

var method = Expression.Lambda<Func<FooFactory, Foo>>(finalExpr, factory).Compile(); 
Foo foo = method(new FooFactory()); //foo is null :(
+2

Sie werfen die Aufgabe weg. Ausdrucksbäume sind rein deklarativ, keine Nebenwirkungen. – Luaan

Antwort

0

Meine schlechte. Ich vergesse, dass Expression.Assign() einen Ausdruck zurückgibt.

Wenn diese stattdessen tun, es funktioniert wunderbar:

List<Expression> expressions = new List<Expression>(); 
expressions.Add(Expression.Assign(fooInstance, call)); 

Dank Luaan für den Tipp.

Verwandte Themen