2015-03-25 7 views
12

Da Xamarin.iOS die Codegenerierung zur Laufzeit nicht unterstützt, warum funktionieren Compile() und DynamicInvoke() wie erwartet?Warum funktioniert LambdaExpression.Compile() unter iOS (Xamarin)?

Zum Beispiel arbeitet der folgende Code in Ordnung:

var lambda = Expression.Lambda(
          Expression.Add(
           Expression.Constant(1), 
           Expression.Constant(2) 
         ) 
      ); 

var f = lambda.Compile(); 
var result = f.DynamicInvoke(); 

// result==3 at this point 

Ist Xamarin den Ausdrucksbaum zur Laufzeit Auswertung statt emittierenden IL-Code?

Antwort

12

Auf Plattformen, die Codegenerierung unterstützen, wird Reflection.Emit-based LambdaCompiler verwendet.

Wenn dies nicht verfügbar ist, wird der Ausdruck interpretiert mit the interpreter. Zum Beispiel gibt es Klassen, die Constant und Add interpretieren.

+0

Ich vermutete so etwas. Ist das irgendwo dokumentiert? –

+0

Während Ihre Antwort sinnvoll ist, würde ich gerne wissen, ob es eine Referenz oder Dokumentation gibt, die dies bestätigt. –

+0

@PhilippeLeybaert Ich konnte keine finden, weshalb ich auf die Quelle schaute. – svick

2

The details of the Xamarin limitations are here.

Sie scheinen nichts im Reflection.Emit Namespace werden, was die große No-No ist. Dein Code muss immer noch AOT'd sein. Ansonsten würde ich mir vorstellen, dass es nicht funktionieren würde.

Aber es gab Beispiele für [native] Entwickler, die das statische Analysewerkzeug von iOS vereiteln und die dynamische Codeeinschränkung umgehen. Ich habe versucht, den Artikel zu finden, konnte ihn aber nicht finden.

Wie auch immer, ich denke nicht, dass Ihr Szenario das veranschaulicht. Ihr Codebeispiel wird weiterhin AOT-kompiliert.

Aber Sie werfen eine wirklich gute Frage auf: Wann wird der Ausdruck ausgewertet?

EDIT:

Ein weiterer SO zum gleichen Thema beantworten: What does Expression.Compile do on Monotouch?

Es gibt auch einige gute Informationen über Expression.Compile() und "full AOT" hier: http://www.mono-project.com/docs/advanced/aot/

EDIT: Nach dem Lesen von mehr, ich denke, ich weiß, was hier vorgeht. Es ist nicht so, dass Expression.Compile() nicht funktioniert ... es ist, dass, wenn Ihr iOS-App-Bundle ist das statische Analyse-Tool iOS unterzogen, wenn Sie es an den App Store übermitteln, wird es nicht die Analyse übergeben, weil es erzeugt dynamisch Code. Sie können also Expression.Compile() verwenden, aber erwarten Sie nicht, dass es in den App Store übernommen wird. Aber wie von @svick erwähnt, wird Ihre Expression.Compile(), wenn Sie die Kompilierungsoption "Full AOT" verwenden, wahrscheinlich zur Laufzeit fehlschlagen oder sogar die Kompilierung fehlschlagen.

+2

Willst du damit sagen, dass der Ausdruck AOT ist? Wie könnte das funktionieren, wenn man bedenkt, dass der Ausdruck zur Laufzeit erstellt wird? – svick

+0

@svick: eine andere SO-Antwort zum gleichen Thema scheint zu deuten, wie ich habe, dass Ausdrücke vom AOT-Compiler in einer Xamarin.iOS-App vorkompiliert werden: http://stackoverflow.com/questions/24977939/what -does-expression-compile-do-on-monotouch – NovaJoe

+0

@svick: Ich wiederhole, was ich sage ist, dass mein Verständnis ist, dass Ausdruck nicht zur Laufzeit gebaut wird, wenn Sie Monos AOT-Compiler verwenden. Es wird zur Kompilierzeit erstellt. – NovaJoe