Reputation: 6222
My goal is to pass a list of expression trees without casting or explicitly specifying type. It's important that I need to pass it as Expression because I do some parsing inside. Example:
var builder = JobRunnerPayloadBuilder<ITestRunner, double>.CreateBuilder();
for (int i = 0; i < 2; i++)
{
builder.Add(x => x.Abc());
}
Then I use builder.Calls
to get all expression trees.
How can I pass arguments to AddRange function without casting or specifying the type explicitly? Something along these lines:
builder.AddRange(parameters.Select(parameter => (Expression<Func<TestObject, int>>) (x => x.DoSomething(parameter))).ToList()) //it doesn't work without explicit cast
Builder class:
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>();
}
}
EDIT: More precise example:
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();
Compiler needs explicit cast to expression here. Is there a way to workaround it? JobRunnerPayloadBuilder was a "try" to avoid specifying the type explicitly but it does work only for single argument
Upvotes: 0
Views: 1847
Reputation: 203812
You can create a simple static method that will allow you to construct an Expression
using a lambda in a context where it knows that the lambda is supposed to be an expression, and allowing it to infer the return return type:
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();
Upvotes: 1