Каков наилучший способ ReadLine по дереву выражений? - PullRequest
1 голос
/ 21 января 2009

Если я хочу получить пользовательский ввод из консоли в мое дерево выражений. Каков наилучший способ сделать это? а как сделать переменную 'name' duck typing?

Вот мой код.

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();
        }
    }
}

1 Ответ

1 голос
/ 21 января 2009

Деревья выражений предназначены для выполнения фиксированной операции - в частности, при доступе к члену будет требоваться известный MemberInfo (и т. Д.) В точке создания дерева выражений (поскольку они неизменяемы).

Вы можете продублировать сгенерированный код из dynamic, если вы играете с 4.0, но, честно говоря, лучший подход в этом сценарии прост: не используйте дерево выражений.

Либо отражение, либо ComponentModel (TypeDescriptor) были бы идеальными для этого динамического доступа к члену.

Также - вызов Compile для чего-то, что вы используете только один раз, не экономит время, и использование DynamicInvoke также не выгодно ... вам нужно использовать типизированную форму делегата (Invoke).

...