Fabrice's weblog

Tools and Source

News

My .NET Toolbox
An error occured. See the script errors signaled by your web browser.
No tools selected yet
.NET tools by SharpToolbox.com

Read sample chapters or buy LINQ in Action now!
Our LINQ book is also available on AMAZON

.NET jobs

Emplois .NET

transatlantys hot news

Contact

Me

Others

Selected content

February 2009 - Posts

ForEach or not ForEach, that is the question

In LINQ in Action, we discuss about the missing ForEach query operator. This is in Chapter 5 "Beyond basic in-memory queries", more precisely in section 5.2.2. There, we indicate that Eric White suggested this operator in his functional programming tutorial, although I'm not able to find the exact reference at the moment in this tutorial.

Since then, a lot of people have been asking for ForEach. This can be seen on Kirill Osenkov's blog, where you'll find links to discussions about whether ForEach is good or bad.
I don't know if we're going to see ForEach appear in .NET. Anyway, it's not very difficult to write your own:

public static void ForEach<T>(this IEnumerable<T> source, Action<T> action)
{
  if (source == null)
    throw new ArgumentNullException("source");
  if (action == null)
    throw new ArgumentNullException("action");

  foreach (var item in source)
    action(item);
}

Cross-posted from http://LinqInAction.net

UI design and prototyping tools

As my previous post shows, I have a growing interest in user experience and UI design patterns. I'm also interested in mockups and prototyping tools, which are of course directly related to UI design and user experience.

Here are the tools I've identified:

Do you know any other tool?
UI design patterns libraries

Over the time, I've collected a set of UI design patterns libraries. Some of them present patterns with descriptions and advices, others collect screenshots of UI designs. With all the available sites, you have a lot of patterns to tap into for your sites and applications!

Feel free to suggest more UI patterns collections.

Null Object design pattern instead of returning null

This is just a quick post to make a plug for the Null Object design pattern. I don't think that it's used a lot, but it's useful to avoid a lot of issues.

It's very common to create or use methods and properties that return null. That's not surprising. It's part of most of the programming languages we use nowadays. However, returning null can lead to issues because if the callers forget to test for null, it will likely provoke a NullReferenceException (or equivalent).

What the Null Object design pattern suggests is to always return a valid instance instead of null. Where you used to return null, you would return an object with a "null" or default behavior/state.

Example:

customer = GetCustomer();
plan = (customer != null) ? customer.Plan : BillingPlan.Basic;

can be replaced with

plan = GetCustomer().Plan

if GetCustomer never returns null, but instead an instance of NullCustomer (or DefaultCustomer), which is a sub-class of the Customer class and whose Plan property is defined as follows:

override BillingPlan Plan
{
  get { return BillingPlan.Basic; }
}

This is the same approach as returning an empty array instead of null. When you return null, the callers need to check for null. When you return an empty array, the callers can try to iterate it without a problem - even if they forget to check for null.

Compare the following methods for example:

Customer[] GetCustomers()
{
  if (!Initialized)
    return null;

  ... // return data
}

and

Customer[] GetCustomers()
{
  if (!Initialized)
    return new Customer[0];

  ... // return data
}


Here are two pointers to learn more about this pattern:

Keep in mind that this is just a pattern, and like the other ones it's not to be used blindly in all cases. Returning null is of course perfectly fine where it makes sense.

Converting LINQ queries from query syntax to method/operator syntax

Yesterday a reader of the LINQ in Action book posted an interesting challenge on the book's forum. It's interesting enough to be reposted it here.

The request was to convert a LINQ query expression (query syntax) to a query operator call chain (method syntax or dot notation). The original query was the following one:

from publisher in SampleData.Publishers
join book in SampleData.Books on publisher equals book.Publisher into publisherBooks
from book in publisherBooks.DefaultIfEmpty()
select new
{
  Publisher = publisher.Name,
  Book = book == default(Book) ? "(no books)" : book.Title
};

This query comes from LINQ in Action. In chapter 4 more precisely, where we cover grouping and joins.

Converting LINQ queries is an interesting exercise because it's not always easy to find the solution but you learn a lot in the process. Often, you'll have to use "tricks". Here the tricks are based on the use of anonymous types. Side note: this is also what you'd use to translate the let keyword.

Here is the solution I gave:

SampleData.Publishers
  .GroupJoin(SampleData.Books,
    publisher => publisher, book => book.Publisher,
    (publisher, publisherBooks) => new { Publisher = publisher, PublisherBooks = publisherBooks })
  .SelectMany(
    group => group.PublisherBooks.DefaultIfEmpty<Book>(),
    (group, book) => new {
      Publisher = group.Publisher.Name,
      Book = (book == null) ? "(no books)" : book.Title
    });

Not as easy to read as your original query, don't you think? See my previous post about Query syntax vs. Method syntax to decide which syntax is best for you.

"How did he manage to convert the query," you may be wondering... Well, even if I know the tricks, the easiest is to use .NET Reflector to decompile the IL.
If you specify ".NET 3.5" for the Optimization option, you'll see the query expression. But if you specify ".NET 2.0", you'll see something that looks close to the above query. You'll have to replace the anonymous methods with lambda expressions and change the name of the anonymous parameters to make the code somewhat more readable, though.

As usual, Reflector is your best friend. It reveals a lot of secrets ;-)

Update: Joe Albahari, of LINQPad fame, suggested other solutions:

1) Calling .ToString() on the query's expression will work just fine if you add AsQueryable() to the first sequence: from publisher in SampleData.Publishers.AsQueryable() join book...
2) If you use LINQPad to run the query, you'll notice it shows lambda translations for all IQueryable-based queries. LINQPad uses its own expression visitor so the result is much more readable than simply calling ToString on the expression.

Crossposted from http://LinqInAction.net

More Posts