Reputation: 678
I'm trying to return an expression from a Select, so I have an expression returning an expression (I think - maybe it's a lambda returning an expression, I'm not sure of the terminology)
If I create a variable that explicitly gives a type to the expression then it works e.g.
housingDivisions.Select(id => {
Expression<Func<Document, bool>> expression = d => d.HousingDivisions.Any(h => h.HousingDivisionId == id);
return expression;
})
however this code seems equivalent (and less wordy)
housingDivisions.Select(id => d => d.HousingDivisions.Any(h => h.HousingDivisionId == id))
but causes a compile error:
Error CS0411 The type arguments for method 'Enumerable.Select(IEnumerable, Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
Is there any way of getting this to compile without having to create an unnecessary variable?
Upvotes: 0
Views: 1375
Reputation: 843
The problem is both the type d
and the delegate type of d => ...
are both unknown and cannot be assumed from anywhere. You can solve both in one go by instantiating the delegate type:
housingDivisions.Select(id => new Func<Document, bool>(d => d.HousingDivisions.Any(h => h.HousingDivisionId == id)))
If you absolutely need the type to be an Expression tree, then you can convert to it by casting:
housingDivisions.Select(id => (Expression<Func<Document, bool>>)(d => d.HousingDivisions.Any(h => h.HousingDivisionId == id)))
The compiler suggests explicitly specifying the arguments. Personally I think that way is a little bit more wordy. But it would look like this:
housingDivisions.Select<int, Expression<Func<Document, bool>>>(id => d => d.HousingDivisions.Any(h => h.HousingDivisionId == id));
Here's an extension method for Selecting an Expression:
public static IEnumerable<Expression<Func<ExprArg, Result>>> SelectExpr<TSource, ExprArg, Result>(this IEnumerable<TSource> source, Func<TSource, ExprArg, Result> func)
{
return source.Select((o) => (Expression<Func<ExprArg, Result>>)((arg) => func(o, arg)));
}
// Use:
housingDivisions.SelectExpr((int id, Document d) => d.HousingDivisions.Any(h => h.HousingDivisionId == id));
Upvotes: 1