Cole Tobin
Cole Tobin

Reputation: 9430

How to add LINQ support to a type?

I want to add LINQ support to a type. How do I accomplish that?

Upvotes: 12

Views: 12613

Answers (3)

Brenton
Brenton

Reputation: 125

Since LINQ to objects works with any class that inherits from IEnumerable<T>, implementing that interface in your class would be enough.

The following link explains on how to implement the IEnumerable interface (although it does not mention LINQ, it will work): http://codebetter.com/davidhayden/2005/03/08/implementing-ienumerable-and-ienumerator-on-your-custom-objects/

Upvotes: 1

Michael Edenfield
Michael Edenfield

Reputation: 28338

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 PListItems):

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.

Upvotes: 26

Arman Hayots
Arman Hayots

Reputation: 2508

You must implement IEnumerable first. Read that first - http://msdn.microsoft.com/en-us/library/9eekhta0.aspx

Upvotes: 1

Related Questions