I stumbled recently on a LINQ limitation. This piece of code cannot compile (even R# doesn’t detect any error) :
using System;
using System.Linq;
class Program {
static void Main(string[] args) {
var query = from i in new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
let fct = (int x) => (x - 5) * (x - 5)
where fct(i) > fct(i - 1)
select i;
foreach (var i in query) { Console.WriteLine(i); }
}
}
The C# compiler error, provoked by fct, is actually Cannot assign lambda expression to a range variable. Trying to replace the lambda by an anonymous method didn’t help, the same error kept popping.
After mulling over a bit I found the following workaround:
using System;
using System.Linq;
class Program {
static void Main(string[] args) {
var query = from i in new[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }
let fct = Function((int x) => (x - 5) * (x - 5))
where fct(i) > fct(i - 1)
select i;
foreach (var i in query) { Console.WriteLine(i); }
}
static Func<T, TResult> Function<T, TResult>(Func<T, TResult> f) {
return f;
}
}
I am not sure it is the best workaround possible, dear reader, can you imagine a cleaner one?
Revised:
- From the answer, 2 nice possibilities were pinpointed: casting to Func<,> or creating explicitly a Func<,>. This is indeed a nicer approach in the sense that it doesn’t involve an extra static method and it is a pure language construct. A minor downside compared to the Function solution proposed is that it forces to precise explicitly the TResult type.
let fct = new Func<int,int>((x => (x - 5) * (x - 5))) let fct = (Func<int,int>) ((x => (x - 5) * (x - 5)))
- I haven’t been explicit enough in the post, the tricky thing is to create a function inside the LINQ query definition, defining the function before the query is not an option.
- Repeating the function definition is not an option, for example purpose here the function defined in the LINQ query is trivial, what I am looking for is a solution for the general case where the function can be complex.