LINQ Farm Seed 0: Operators in LINQ to Objects


LINQ Farm Seeds are short posts, designed to be read in a few minutes. This one covers enumerating the operators used in LINQ to Objects. The source code for this project is available in the LINQ Farm on Code Gallery.

The LINQ to Objects operators are implemented as extension methods on the Enumerator class. The following simple LINQ query gives you a fairly clean listing of those operators:

var query = from m in typeof(Enumerable).GetMethods()
   orderby m.Name
   where m.DeclaringType == typeof(Enumerable)
   group m by m.Name into g
   orderby g.Count()
   select new { Operator = g.Key, OverloadCount = g.Count() };   
   Console.WriteLine("Approximate operator count: {0}", query.Count());

   foreach (var q in query)
   {
     Console.WriteLine(q);
   }

The output from this query looks something like this:

Approximate operator count: 50
{ Operator = All, OverloadCount = 1 }
{ Operator = AsEnumerable, OverloadCount = 1 }
{ Operator = Cast, OverloadCount = 1 }
\\ Code omitted here
{ Operator = GroupBy, OverloadCount = 8 }
{ Operator = Average, OverloadCount = 20 }
{ Operator = Sum, OverloadCount = 20 }
{ Operator = Max, OverloadCount = 22 }
{ Operator = Min, OverloadCount = 22 }

This query uses LINQ to Reflection, a feature that is built into C# 3.0. It allows you to write link queries against the code in your program.

The query begins by asking for all the methods found in the type Enumerable:

   from m in typeof(Enumerable).GetMethods()

The next line orders these methods by name:

   orderby m.Name

The data is filtered so reveal only the methods declared in this class, and not any that are inherited. This ensures that we don’t see methods inherited from class object such as Equals, GetHashCode, GetType and ToString. All that is left are the extensions methods declared in this class to be used in LINQ to Objects:

   where m.DeclaringType == typeof(Enumerable)

Many of these methods are overloaded. For instance, the Min method is overloaded 22 times. Our listing would be very long if we included them all. So we group them by name to ensure that only one instance of each method is included:

   group m by m.Name into g

We order them again, this time by count:

   orderby g.Count()

By ordering them twice we first ensure that they are ordered by the number of times they are overloaded, and by their alphabetical position.

The end result is a listing of all the LINQ to Objects query operators, ordered first by count, and then alphabetically:

Name Overloads
All 1
AsEnumerable 1
Cast 1
Concat 1
ElementAt 1
ElementAtOrDefault 1
Empty 1
OfType 1
Range 1
Repeat 1
Reverse 1
Skip 1
Take 1
ToArray 1
ToList 1
Any 2
Contains 2
Count 2
DefaultIfEmpty 2
Distinct 2
Except 2
First 2
FirstOrDefault 2
GroupJoin 2
Intersect 2
Join 2
Last 2
LastOrDefault 2
LongCount 2
OrderBy 2
OrderByDescending 2
Select 2
SequenceEqual 2
Single 2
SingleOrDefault 2
SkipWhile 2
TakeWhile 2
ThenBy 2
ThenByDescending 2
Union 2
Where 2
Aggregate 3
SelectMany 4
ToDictionary 4
ToLookup 4
GroupBy 8
Average 20
Sum 20
Max 22
Min 22

 

If you would like to see the actual declaration for this class, type it once into the Visual Studio editor, then select it and press F12. You can also right click on it, and choose “Go to definition.”

I want to get my hands dirty; show me more LINQ Farm posts!

kick it on DotNetKicks.com

Comments (10)

  1. You’ve been kicked (a good thing) – Trackback from DotNetKicks.com

  2. Jon Skeet says:

    Am I right in thinking you mean OverloadCount instead of OverrideCount?

  3. Jon Skeet says:

    Oh, and a bad thing about this – it’s not very efficient. In particular, it needs to keep all the information in the group even when it’s just counting it.

    What you need is some sort of "push" mechanism 🙂

    http://msmvps.com/blogs/jon.skeet/archive/2008/01/04/quot-push-quot-linq-revisited-next-attempt-at-an-explanation.aspx

    (Sorry, couldn’t resist.)

    Jon

  4. LINQ Farm Seeds are short posts designed to be read in a few minutes. The first seed showed how to list

  5. ccalvert says:

    Thanks Jon. Yes, I meant to right Overload.

  6. Andre Moraes says:

    I wonder how this linq sql is vb.net

    var query = from m in typeof(Enumerable).GetMethods()

      orderby m.Name

      where m.DeclaringType == typeof(Enumerable)

      group m by m.Name into g

      orderby g.Count()

      select new { Operator = g.Key, OverloadCount = g.Count() };  

  7. LINQ Recipes says:

    Charlie Calvert’s LINQ Farm Seeds

  8. Hot Topics says:

    Charlie Calvert is a C# Community Evanelist at Microsoft and his blog is filled with informative posts

  9. David Nelson says:

    What is LINQ to Reflection? Your code looks like plain old LINQ to me…

  10. Lexapro. says:

    Lexapro. Lexapro cessation vertigo. Prozac lexapro. Lexapro and weight loss.