Friday, January 05, 2007

Collection initializers

Freya have another new feature borrowed from C# 3.0: collection initializers.
var L := new List[Integer]![1, 2, 3, 4];
As you can see, an array literal can be appended to the creation of any class implementing the generic ICollection[T] interface type. But, this time, the array literal doesn't generates an array at runtime. Instead, for each item in the literal, a call to the method Add, from the collection, is generated.
In order to realize why we need collection initializers, you must weight the alternative method:
var L := new List[Integer]([1, 2, 3, 4]);
In this case, the array literal is passed as a parameter to the constructor call. However, the parameter is declared as IEnumerable[T]. Can you see what it means? A temporal array must be generated and initialized, item by item. Then, the array must be casted as a IEnumerable[T] reference, which will be passed to the constructor. Inside the constructor, GetEnumerator is called, and a second temporal object is created. Finally, a loop is performed, in order to add an item for each enumerated item.

Labels: ,

Monday, January 02, 2006

Object initializers

Take a look at this code:
// C# 3.0
var a = new Point { X = 0, Y = 1 };
This fragment has been copied from the C# 3.0 specification preview. According to that document, the above instruction should be interpreted as:
// C# 3.0
var a = new Point();
a.X = 0;
a.Y = 1;
So, we have a "normal" instance construction followed by property or field assignments. Does this remind you any other existing C# feature? Sure, that's how custom attributes are instantiated. Custom attributes mix positional parameters corresponding to constructor parameters, and named parameters, which must be translated as post-construction assignments. We could extend the syntax from custom attributes to object creation:
// A proposal
var a = new Point(X = 0, Y = 1);
Of course: I know object initializers were proposed for C# 3.0 as part of the support for anonymous types. In C# 3.o, you could drop the "constructor part" like this:
// Anonymous types in C# 3.0
var p1 = new {
Name = "Lawnmower", Price = 495.00 };
But then, why not this?
// Anonymous types in C# 3.0: a proposal
var p1 = new(
Name = "Lawnmower", Price = 495.00 );
Is this a good idea? I still have to check the 3.0 proposal, to see whether there is any other reason to prefer the curly braces initializers (nested initializers, for instance). In any case, I think it's better for Freya to adopt the "custom attribute initialization syntax" for object initializers: the literal translation of C#'s curly braces would be a begin/end pair. So, we could initialize a Point object in Freya this way:
// A proposal for Freya 1.0
var p := new Point(X := 0, Y :=0);
var tb := new DataTable(
'Customers', CaseSensitive := true);
How do you like it?

Labels: ,