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;
}
}
// ...
Saturday, July 19, 2008 at 12:37
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});
aCoder,
yes, you are absolutely right.
[...] 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.
Patric,
You do not have server-side query execution, compiler support with strong typing or parallel execution with python.
Sorry, I used "python" in exchange for "boo." Boo's syntax is strongly influenced by python's.
@Patric,
Yes, Boo is much better.
Yet it lacks nice Linq syntax with the IDE support for that like in VS+R#