Implementing LINQ simply means implementing the methods LINQ expects to be there, such as Where
or Select
, with the correct signatures. Despite common perception, you do not have to implement the IEnumerable
interface for your class to support LINQ. However, implementing IEnumerable
will automatically get you the entire set of LINQ methods on the Enumerable
class almost for free -- you only have to implement GetEnumerator
and an IEnumerator
class.
There are a couple of examples on how to implement IEnumerable
on my blog, in this post about the Iterator pattern.
However, if it doesn't make sense for your class to be enumerable, you don't need to do so. You just need to implement the appropriate LINQ methods directly. LINQ doesn't actually care how the methods get defined, so long as the C# compiles. That is, if you write:
from p in myPlist where p.Thing == "Thing" select p;
the C# compiler translates this into:
mpPlist.Where(p => p.Thing == "Thing").Select(p => p);
As long as that compiles, LINQ will work. To see the correct signatures for the methods, look as the MSDN documentation's list of LINQ query methods. For example (assume that your PList
was a list of PListItem
s):
public class PList
{
public IEnumerable<PListItem> Where(Func<PListItem, bool> predicate)
{
foreach (var item in this.items)
{
if (predicate(item))
{
yield return item;
}
}
}
}
While implementing LINQ directly in this manner gives you a lot more control over how it behaves, it's a lot more work to get it right, and you need to understand the implications of your return values, and chaining LINQ calls, etc. In general, if you can get away with making your class implement IEnumerable
and let C# do all the work for you, things go much easier.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…