Extension methods syntax vs query syntax

Viewed 34309

I'm trying to get a handle on if there's a good time to use standard linq keywords or linq extension methods with lambda expressions. They seems to do the same thing, just are written differently. Is it purely a matter of style?

var query = from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p;

// or with extension methods:
var query = Products
    .Where(p => p.Name.Contains("foo"))
    .OrderBy(p => p.Name);

They're very similar with the second example being a bit more terse, but perhaps less expressive if you don't know what the => is doing.

Other than writing terse code, are there other advantages to using the extension methods as opposed to the LINQ syntax?

7 Answers

Honestly, sometimes it can be situational once you start using Funcs and Actions. Say you are using these three funcs:

  Func<DataClasses.User, String> userName = user => user.UserName;
  Func<DataClasses.User, Boolean> userIDOverTen = user => user.UserID < 10;
  Func<DataClasses.User, Boolean> userIDUnderTen = user => user.UserID > 10;

As you can see the first one replaces the lamdba expression to get the user name, the second replaces a lamdba expression used to check if the ID is lower than 10, and let's face it, the third should be pretty easy to understand now.

NOTE: This is a silly example but it works.

  var userList = 
    from user in userList
    where userIDOverTen(user)
    select userName;

Versus

  var otherList =
    userList
    .Where(IDIsBelowNumber)
    .Select(userName)

In this example, the second is a little less verbose since the extension method can make full use of the Func, but he Linq expression can't since it is look just for a Boolean rather than a Func that returns boolean. However, this is where it might be better to use the expression language. Say you already had a method that takes in more than just a user:

  private Boolean IDIsBelowNumber(DataClasses.User user, 
          Int32 someNumber, Boolean doSomething)
  {
    return user.UserID < someNumber;
  }

Note: doSomething is just there because of the where extension method being ok with a method that takes in a user and integer and returns boolean. Kind of annoying for this example.

Now if you look at the Linq query:

  var completeList =
     from user in userList
     where IDIsBelowNumber(user, 10, true)
     select userName;

You're good for it. Now the Extension Method:

  var otherList =
    userList
    .Where(IDIsBelowNumber????)
    .Select(userName)

Without a lambda expression, I really can't call that method. So now what I have to do is create a method that creates a Func based off the original method call.

   private Func<DataClasses.User, Boolean> IDIsBelowNumberFunc(Int32 number)
   {
      return user => IDIsBelowNumber(user, number, true);
   }

And then plug it in:

  var otherList =
     userList
     .Where(IDIsBelowNumberFunc(10))
     .Select(userName)

So you can see, sometimes it may just be easier to use the query approach at times.

One advantage to using LINQ extension methods (method-based queries) is that you can define custom extension methods and it will still read fine.

On the other hand, when using a LINQ query expression, the custom extension method is not in the keywords list. It will look a bit strange mixed with the other keywords.

Example

I am using a custom extension method called Into which just takes a string:

Example with query

var query = (from p in Products
    where p.Name.Contains("foo")
    orderby c.Name
    select p).Into("MyTable");

Example with extension methods

var query = Products
                   .Where(p => p.Name.Contains("foo"))
                   .OrderBy(p => p.Name)
                   .Into("MyTable");

In my opinion the latter, using a method-based query, reads better when you have custom extension methods.

They compile the same, and are equivalent. Personally, I prefer the lambda (extension) methods for most things, only using the statements (standard) if I'm doing LINQ to SQL or otherwise trying to emulate SQL. I find that the lambda methods flow better with code, whereas the statements are visually distracting.

I prefer the extension method syntax when I use Linq methods that have no query syntax equivalent, such as FirstOrDefault() or others like that.

One advantage of extension methods/lynda expressions is the additional operators that is offered like Skip and Take. For example, if you are creating a pagination method, being able to skip the first 10 records and take the next 10 is easy to implement.

Related