创建表达式列表

时间:2017-01-17 15:53:50

标签: c# expression

我的目标是传递表达式树列表而不强制转换或显式指定类型。重要的是我需要将其作为Expression传递,因为我在内部进行了一些解析。 例如:

  var builder = JobRunnerPayloadBuilder<ITestRunner, double>.CreateBuilder();
   for (int i = 0; i < 2; i++)
{
   builder.Add(x => x.Abc());
}

然后我使用builder.Calls获取所有表达式树。

如何在不强制转换或明确指定类型的情况下将参数传递给AddRange函数?这些方面的东西:

builder.AddRange(parameters.Select(parameter => (Expression<Func<TestObject, int>>) (x => x.DoSomething(parameter))).ToList()) //it doesn't work without explicit cast

构建器类:

public class JobRunnerPayloadBuilder<TRunner, TResult>
{
    public List<Expression<Func<TRunner, TResult>>> Calls { get; } = new List<Expression<Func<TRunner, TResult>>>();

    public JobRunnerPayloadBuilder<TRunner, TResult> Add(Expression<Func<TRunner, TResult>> call)
    {
        Calls.Add(call);
        return this;
    }

    public JobRunnerPayloadBuilder<TRunner, TResult> AddRange(IEnumerable<Expression<Func<TRunner, TResult>>> calls)
    {
        Calls.AddRange(calls);
        return this;
    }

    public static JobRunnerPayloadBuilder<TRunner, TResult> CreateBuilder()
    {
        return new JobRunnerPayloadBuilder<TRunner, TResult>();
    }
}

编辑: 更精确的例子:

public class TestObject
    {
        public int DoSomething(string param1)
        {
            return 1;
        }
    }

  var parameters = new List<string>() { "a", "b", "c" }; // generated somewhere earlier.



var expressions = parameters.Select(parameter => (Expression<Func<TestObject, int>>) (x => x.DoSomething(parameter))).ToList();

编译器需要在这里显式转换为表达式。有办法解决它吗? JobRunnerPayloadBuilder是一个“尝试”,以避免明确指定类型,但它只适用于单个参数

1 个答案:

答案 0 :(得分:1)

您可以创建一个简单的静态方法,允许您在上下文中使用lambda构造Expression,它知道lambda应该是一个表达式,并允许它推断返回类型:

public static Expression<Func<TSource, TResult>> CreateExpression<TSource, TResult>(
    Expression<Func<TSource, TResult>> expression)
{
    return expression;
}
var expressions = parameters.Select(parameter => 
    CreateExpression((TestObject x) => x.DoSomething(parameter))
.ToList();