Pages

Wednesday, January 25, 2017

What does this code do? Extended explanation

Ayende posted some code that didn't work as expected, and an explanation of why. You can read his full post here.

What does this code do?

But I'm not as bright as his readers, and was still mighty confused. It took me about ten minutes to finally see what was going on.

Ayende's original code is this:

var doc = new Dictionary<string,object>
{
    ["@metadata"] = new Dictionary<string, object>
    {
        ["@id"] = "users/1"
    }
    ["Name"] = "Oren"
};


Console.WriteLine(doc["Name"]);

The final statement fails, because doc is actually equal to a string value of "Oren", not the dictionary object. Why? And--for me--I couldn't understand why it was compiling at all.

It took me a while to see the syntax parsing, and remember that C# can be very forgiving of spaces. I'm not a beginner, but it's sort of a beginner mistake. For other readers like me who aren't as bright (if you have any!), here's another look.

While it appeared to me an element was being set completely outside of the declaration, the element is being set on the declared dictionary.

The final syntax is:

var item = NewDictionary[element] = value;

But that syntax can look like this:

var item = NewDictionary              [element] = value;

Code samples

//spaces before the element don't matter
var item = new Dictionary<string, object> {}    ["a"] = 1;
//is the same as
var item = new Dictionary<string, object> { }["a"] = 1;

//For clarity, we replace the declaration with its assignment.
var dic = new Dictionary<string, object> {};
var item = dic     ["a"] = 1;
//is the same as
var item = dic["a"] = 1;

I looked for other examples of where this can be done. The simplest array case doesn't compile:

//This is OK.
int[] items = new int[1] {1};
int item = items [0] = 2;

//But this isn't.
int[] items = new int[1] { 1 } [0] = 2;

Hashtable works the same as Dictionary, which is logical.

//OK
var h = new Hashtable();
h [0] = 1;

//OK, too.
var h = new Hashtable() [0] = 1;

Thanks, Ayende, for getting my brain working!

No comments:

Post a Comment