Quel est le meilleur moyen de lire ReadLine by Expression Tree?
-
19-08-2019 - |
Question
Si je souhaite obtenir une entrée utilisateur de la console dans mon arbre d'expression. Quelle est la meilleure façon de le faire? et comment faire une saisie de type 'nom' de canard variable?
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();
}
}
}
La solution
Les arborescences d'expression sont conçues pour effectuer une opération fixe - en particulier, l'accès de membre va vouloir un MemberInfo
(etc) connu au moment de la création de l'arborescence d'expression (car ils sont immuables) .
Vous pouvez dupliquer le code généré à partir de dynamic
si vous jouez avec la version 4.0, mais pour être honnête, la meilleure approche dans ce scénario est tout simplement: n'utilisez pas d'arborescence d'expression.
La réflexion ou ComponentModel
( TypeDescriptor
) serait idéal pour cet accès dynamique à un membre.
De plus, appeler Compiler
sur quelque chose que vous n'utilisez qu'une fois n'enregistre pas à tout moment, et utiliser DynamicInvoke
n'est pas non plus ... vous devez utiliser le type saisi formulaire de délégué ( Invoke
).