如果我想从Console获取用户输入到我的表达式树。最好的方法是什么?以及如何使变量'name'鸭子打字?
这是我的代码。
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();
}
}
}
答案 0 :(得分:1)
表达式树旨在执行固定操作 - 特别是,成员访问在表达式树创建时需要一个已知的MemberInfo
(等等)(因为它们是不可变的)。
如果你正在使用4.0,你可以复制generated code from dynamic
,但说实话,这种情况下更好的方法就是:不要使用表达式树。
反射或ComponentModel
(TypeDescriptor
)非常适合动态访问会员。
此外 - 只对您使用过一次的内容调用Compile
不会保存任何时间,并且使用DynamicInvoke
也不是......您需要使用键入的委托形式({{1 }})。