Latest Replies
Saturday
Jul192008

Generator pattern in C# .NET

Boo language has nice code pattern called Generator:

// Generator expressions are defined through the pattern:
<expression> for <declarations> in <iterator> [if|unless <condition>]

// Generator expressions can be used as return values:
def GetCompletedTasks():
      return t for t in _tasks if t.IsCompleted

// Generator expressions can be stored in variables:
oddNumbers = i for i in range(10) if i % 2

This pattern simply creates some IEnumerable object via the syntax transformation. We can not have this sugar in C# yet, but that's how we can leverage the concept:

// Simple syntax
var customerList = new List<Customer>();
for (int i = 0; i < 40; i++)
{
  customerList.Add(new Customer
  {
    Name = "Customer_" + i
  });
}

// generator + LINQ syntax
var customers = Generator.For(40).Select(i => new Customer
{
  Name = "Customer_" + i
});

Both pieces of code do the same thing; they create enumeration of 40 Customers _with names in "Customer[ID]" format.

The first approach is the traditional one, while the second uses Generator to create enumerator from 0 to 40 (with lazy evaluation) and then LINQ to transform enumerator entries into Customers.

I'm not sure if the generator could be useful in the base code, but it does speed up writing some unit tests a little bit. Here is the sample backing _Generator _method:

public static class Generator
{
  public static IEnumerable<int> For(int max)
  {
    for (int i = 0; i < max; i++)
    {
      yield return i;
    }
  }

  // ...
« Web Deployment Projects fail without errors | Main | Linq queries with parameters for your ORM IRepository »

Reader Comments (7)

Unless I miss something, there's already a built-in one in System.Linq:

Enumerable.Range(0, 40).Select(i => new Customer{Name = "Name_" + i});

July 21, 2008 | Unregistered CommenteraCoder

aCoder,

yes, you are absolutely right.

July 29, 2008 | Unregistered CommenterRinat Abdullin

[...] you remember my post on the Generator pattern? If you only need a numeric inline generator, then System.Linq already provides one. Look out for [...]

This is what Linq is all about:

python:
t for t in _tasks if t.IsCompleted

Linq:
from t in _tasks where t.IsCompleted select t;

It's a little more verbose but not exremely so.

September 29, 2008 | Unregistered CommenterPatrick Chasco

Patric,

You do not have server-side query execution, compiler support with strong typing or parallel execution with python.

September 30, 2008 | Unregistered CommenterRinat Abdullin

Sorry, I used "python" in exchange for "boo." Boo's syntax is strongly influenced by python's.

October 21, 2008 | Unregistered CommenterPatrick Chasco

@Patric,

Yes, Boo is much better.

Yet it lacks nice Linq syntax with the IDE support for that like in VS+R#

October 21, 2008 | Unregistered CommenterRinat Abdullin

PostPost a New Comment

Enter your information below to add a new comment.

My response is on my own website »
Author Email (optional):
Author URL (optional):
Post:
 
Some HTML allowed: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <code> <em> <i> <strike> <strong>