2009-01-21 8 views
1

Si je veux obtenir une entrée d'utilisateur de la console à mon arbre d'expression. Quelle est la meilleure façon de le faire? et comment faire du typage de canard variable 'name'?Quelle est la meilleure façon de ReadLine par Expression Tree?

Voici mon code.

using System; 
using System.Reflection; 
using System.Collections.Generic; 
using Microsoft.Linq; 
using Microsoft.Linq.Expressions; 

namespace ExpressionTree 
{ 
    class Program 
    { 
     static void Main(string[] args) 
     { 
      List<Expression> statements = new List<Expression>(); 

      // Output 
      MethodInfo Write = typeof(System.Console).GetMethod("Write", new Type[] { typeof(string) }); 
      ConstantExpression param = Expression.Constant("What is your name? ", typeof(string)); 
      Expression output = Expression.Call(null, Write, param); 
      statements.Add(output); 

      // Input 
      MethodInfo ReadLine = typeof(System.Console).GetMethod("ReadLine"); 
      ParameterExpression exprName = Expression.Variable(typeof(String), "name"); 
      Expression exprReadLine = Expression.Call(null, ReadLine); 

      // .NET 4.0 (DlR 0.9) from Microsoft.Scripting.Core.dll 
      // Expression.Assign and Expression.Scope 
      ScopeExpression input = Expression.Scope(Expression.Assign(exprName, exprReadLine), exprName); 
      statements.Add(input); 

      // Create the lambda 
      LambdaExpression lambda = Expression.Lambda(Expression.Block(statements)); 

      // Compile and execute the lambda 
      lambda.Compile().DynamicInvoke(); 

      Console.ReadLine(); 
     } 
    } 
} 

Répondre

1

arbres d'expression sont conçus pour effectuer une opération fixe - en particulier, l'accès des membres va vouloir un connu MemberInfo (etc) au moment de la création de l'arbre d'expression (car ils sont immuables).

Vous pouvez dupliquer le generated code from dynamic si vous jouez avec 4.0, mais pour être honnête, la meilleure approche dans ce scénario est simplement: n'utilisez pas d'arbre d'expression.

Une réflexion ou ComponentModel (TypeDescriptor) serait idéal pour cet accès dynamique à un membre. En outre, appeler Compile sur un élément que vous n'utilisez qu'une seule fois ne vous permet pas de gagner du temps, et utiliser DynamicInvoke n'est pas non plus ... vous devez utiliser le formulaire de délégué typé (Invoke).

+0

@MarkGravell: J'ai trouvé vos réponses sur les arbres d'expression et les types dynamiques et je les ai trouvés très utiles. Je vous remercie! Je suis cependant, perplexe à [ce problème] (http://stackoverflow.com/q/24939618/938668). Si vous avez l'occasion d'y jeter un coup d'œil, j'apprécierais vos commentaires à ce sujet. –

Questions connexes