I think the easiest way to do this is by creating new functions (such as _Where()
, _Take()
) that just call the Where
and Take
function, but also save the fact that you called them and with which arguments. Then later you can read them again.
The downside of this is that you need to somehow store which calls belong to which. I.e. if you have two statements list.Where().Where()
and list.Where().Take()
you need to save which calls belong to the first line and which belong to the second.
You could also try to make these sepcialized functions return a tuple containing both the result and the call information. Then you should create two functions for each linq method: one which just accepts an enumerable and one which accepts a tuple of an enumerable and the call information from before. This way you can add the new call information to the old one. If you use extension functions, you have to extend the enumerable and the tuple of course.
Edit:
Let me add an example of my thinking... Note that it is difficult to perfectly serialize the function given in the Where
function. It is possible, check for example Convert Func delegate to a string
Overloads.cs:
public static class Overloads
{
public static (IEnumerable<T>, List<string>) Where_<T>(this IEnumerable<T> inp, Func<T, bool> predicate)
{
return (inp.Where(predicate), new List<string> { ".Where(...)" });
}
public static (IEnumerable<T>, List<string>) Where_<T>(this (IEnumerable<T>, List<string>) inp, Func<T, bool> predicate)
{
inp.Item2.Add(".Where(...)");
return (inp.Item1.Where(predicate), inp.Item2);
}
public static (IEnumerable<T>, List<string>) Take_<T>(this IEnumerable<T> inp, int count)
{
return (inp.Take(count), new List<string> { $".Take({count})" });
}
public static (IEnumerable<T>, List<string>) Take_<T>(this (IEnumerable<T>, List<string>) inp, int count)
{
inp.Item2.Add($".Take({count})");
return (inp.Item1.Take(count), inp.Item2);
}
}
Example run:
public static void Main(string[] args)
{
var a = new List<int> { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
var (result, calls) = a
.Where_(x => x % 2 == 0)
.Where_(x => x % 3 == 0)
.Take_(1);
Console.WriteLine(string.Join(", ", result));
Console.WriteLine(string.Join(", ", calls));
}
Output:
0
.Where(...), .Where(...), .Take(1)