Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding LINQ to my classes

Tags:

c#

linq

I want to add LINQ support to my Apple Property List (Property List) parser (binary, JSON, and XML) so that I can use SQL like queries on it like you can with System.Xml. It works by parsing the file completely and saving it on the heap. (like System.Xml does).

I have been Googling and can't seem to understand any of it (I get a lot of Using LINQ to SQL Classes pages). The guide over on MSDN, I don't understand either. What do I need to do?

like image 869
Cole Tobin Avatar asked Jun 17 '12 02:06

Cole Tobin


1 Answers

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.

like image 74
Michael Edenfield Avatar answered Sep 27 '22 23:09

Michael Edenfield