I thought it would be nice to do something like this (with the lambda doing a yield return):
public IList Find(Expression
Eric Lippert has written an excellent series of articles on the limitations (and design decisions influencing those choices) on iterator blocks
In particular iterator blocks are implemented by some sophisticated compiler code transformations. These transformations would impact with the transformations which happen inside anonymous functions or lambdas such that in certain circumstances they would both try to 'convert' the code into some other construct which was incompatible with the other.
As a result they are forbidden from interaction.
How iterator blocks work under the hood is dealt with well here.
As a simple example of an incompatibility:
public IList GreaterThan(T t)
{
IList list = GetList();
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item; // This is not allowed by C#
}
return items.ToList();
}
The compiler is simultaneously wanting to convert this to something like:
// inner class
private class Magic
{
private T t;
private IList list;
private Magic(List list, T t) { this.list = list; this.t = t;}
public IEnumerable DoIt()
{
var items = () => {
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}
}
}
public IList GreaterThan(T t)
{
var magic = new Magic(GetList(), t)
var items = magic.DoIt();
return items.ToList();
}
and at the same time the iterator aspect is trying to do it's work to make a little state machine. Certain simple examples might work with a fair amount of sanity checking (first dealing with the (possibly arbitrarily) nested closures) then seeing if the very bottom level resulting classes could be transformed into iterator state machines.
However this would be
In your example like so:
public IList Find(Expression> expression)
where T : class, new()
{
return FindInner(expression).ToList();
}
private IEnumerable FindInner(Expression> expression)
where T : class, new()
{
IList list = GetList();
var fun = expression.Compile();
foreach (var item in list)
if (fun.Invoke(item))
yield return item;
}