AnswerWhat does this code do?
This was a surprising shock, this code seems so simple, but it does something very different than what I would expect.
The question is why?
As it turns out, we are missing one character here:
Notice the lack of the comma? Let us see how the compiler is treating this code by breaking it apart into steps, shall we?
First, let us break it into two statements:
Note that we moved the name line into the first statement, since there isn’t a command here. But what is it actually doing? This looks very strange, but that is just because we have the dictionary initializer here. If we drop it, we get:
And that make a lot more sense. If we’ll break it all down, we have:
And that explains it all, make perfect sense, and a very nasty trap. We run into it accidently in production code, and it was near impossible to figure out what was going on or why it happened.
More posts in "Answer" series:
- (22 Jan 2025) What does this code do?
- (05 Jan 2023) what does this code print?
- (15 Dec 2022) What does this code print?
- (07 Apr 2022) Why is this code broken?
- (20 Jan 2017) What does this code do?
- (16 Aug 2011) Modifying execution approaches
- (30 Apr 2011) Stopping the leaks
- (24 Dec 2010) This code should never hit production
- (21 Dec 2010) Your own ThreadLocal
- (11 Feb 2010) Debugging a resource leak
- (03 Sep 2009) The lazy loaded inheritance many to one association OR/M conundrum
- (04 Sep 2008) Don't stop with the first DSL abstraction
- (12 Jun 2008) How many tests?
Comments
That is a nasty bug!
I think its easier to understand íf you just remove the breaklines from the statement
Isn't it another issue that the code is using object initializers on collections instead of collection initalizers?
That example code is just terrible for easy debugging. I think people should use object initializers with care. Better use an extra variable for better readability and better debugging.
I'm confused. The original code as is gives KeyNotFoundException , but this reads as if it doesn't...
Brad, Yes, that is the point. This is very surprising code
But what I don't understand, and your explanation code doesn't clarify, is why
["Name"] = "Oren"
works at all? It's outside of the collection initializer.Why does this compile, and why does test1 end up being a String? Why is the Dictionary initialization being bypassed?
It seems to me this is a C# bug, because it only works with
var
. Neither of these compiles.Charles, You need to break it into component parts.
When it looks like this:
It is easier to understand
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:
But that syntax can look like this:
Code samples
I looked for other examples of where this can be done. The simplest array case doesn't compile:
Hashtable works the same as Dictionary, which is logical.
Thanks for getting my brain working!
Comment preview