This is a mirror of official site:

Fun with Object and Collection Initializers

| Sunday, February 17, 2013

Is it an object initializer? Is it a collection initializer? (Parenthetically speaking...)

In a lot of C# code, an assignment expression is just a normal expression. That means there's potentially room for ambiguity, in exactly the same kind of situation as above - when sometimes we want a collection initializer, and sometimes we want an object initializer. Consider this sample class:

using System; 
using System.Collections; 

class Weird : IEnumerable 
    public string Foo { get; set; } 
    private int count; 
    public int Count { get { return count; } } 
    public void Add(string x) 
    IEnumerator IEnumerable.GetEnumerator() 
        throw new NotSupportedException(); 

As you can see, it doesn't actually remember anything passed to the Add method, but it does remember how many times we've called it.

Now let's try using Weird in two ways which only differ in terms of parentheses. First up, no parentheses:

string Foo = "x"; 
Weird weird = new Weird { Foo = "y" }; 
Console.WriteLine(Foo);         // x 
Console.WriteLine(weird.Foo);   // y 
Console.WriteLine(weird.Count); // 0

Okay, so it's odd having a local variable called Foo, but we're basically fine. This is an object initializer, and it's setting the Foo property within the new Weird instance. Now let's add a pair of parentheses:

string Foo = "x"; 
Weird weird = new Weird { (Foo = "y") }; 
Console.WriteLine(Foo);         // y 
Console.WriteLine(weird.Foo);   // Nothing (null) 
Console.WriteLine(weird.Count); // 1

Just adding those parenthese turn the object initializer into a collection initializer, whose sole item is the result of the assignment operator - which is the value which has now been assigned to Foo.

Needless to say, I don't recommend using this approach in real code...

QR: Inline image 1

Posted via email from Jasper-net