Home > .NET 3.5, C# 3.0 > Using Object Initializers on Dictionary

Using Object Initializers on Dictionary

March 13, 2008

I’m still going strong on the ASP.NET MVC development, and I wanted to experiment with HtmlHelper.Select rather than hard coding specific values into my View. To that end, I am building a supporting class that will retain static properties (which I’m sure will be cached once I figure out how to do that). Some of these properties are lists of information, like product types and prices, that could be fed from a database table. Others may be static lists with the potential to become database driven, like state codes and names. Ultimately, where they come from does not matter, but in my coding today I came across something interesting.

To begin this process, I decided to populate a static Dictionary<string, string> with a list of codes and values. This is a small list, so for initial testing I just wanted to hard code the values. It has become a habit for me to use Object Initializers whenever possible, so naturally this seemed a perfect fit. But let me ask you: have you ever tried this? I have to admit that at first I was a little stumped. I first tried to build a method tree (a concept that really doesn’t exist in C#):

BusinessTypes = new Dictionary<string, string>()
.Add("APP", "Appraisal")
.Add("GOV", "Government")
.Add("INS", "Insurance")
.Add("LAW", "Legal")
.Add("LEN", "Lending")
.Add("REL", "Real Estate")
.Add("RES", "Research")
.Add("OTH", "Other");

Even though I didn’t really expect this to work, I thought it would be interesting to see what happened. [This could be a good candidate for a future language enhancement.] Naturally it failed, but in an unexpected fashion. The first call to .Add passed the compiler, but the second call to .Add threw the following error:

Operator ‘.’ cannot be applied to operand of type ‘void’

I also tried adding the method call inside the Initializer block, but since you can’t put method calls inside of Initializer blocks I pretty much knew that wouldn’t work either.

So I looked at it some more and asked myself “what is the Dictionary looking for?” My answer was “a KeyValuePair”, so I tried that next:

BusinessTypes = new Dictionary()
{
    new payday us fast cash loan,fast cash payday loancash till payday loan,cash loan payday,advance cash cash loan payday paydayloan oneclickcash paydaycash fast loan paydaycash advance loan illinois,5 advance cash illinois loanfull pay video pokerbest video pokerinternet casino craps,internet casino,internet casino gambling gamefree online casino gamblingduces wild video pokercasino link online suggestno deposit bonus online casino,free online gambling casino bonus,online casino bonusplay blackjack online freefree video poker gamescraps free online play,casino craps free gambling online,free online crapsfree online casino,online casino,top online casinoplaying blackjackplay free casinofree casino cash bonus,casino cash,free cash casinofree video poker gamereal money backgammonplay roulette onlinefree casino moneytriple play video pokerfree roulette,free roulette download,play free rouletteroulette gambling,best gambling online roulette,online roulette gamblingplay black jack online freeonline gambling casino,gambling casino online bonus,free online casino gamblingcasino download,free online casino download,download online casino gamemicrogaming casino bonusbaccarat card game,baccarat game,baccarat the internet casino gamecasino no deposit bonus code,online casino sign up bonus,casino bonusvideo poker for winnersvideo poker strategy,free video poker,video pokerkeno gameplay slots,play for fun online slots,free slots play for freecraps rulesplay free slots,free slots,free online slots gameinternational online casinovideo poker machineshand held video pokercraps gambling strategy,craps gambling game,gambling crapsbest casino bonus888 black jackfree online slots no download,no download free slots game,free slots no downloadblack jack downloadplay casino game onlinetournament backgammon888 poker,888 poker info,888 poker tournamentbest online casino bonus KeyValuePair<string, string>("APP", "Appraisal"),
    new KeyValuePair<string, string>("GOV", "Government"),
    new KeyValuePair<string, string>("INS", "Insurance"),
    new KeyValuePair<string, string>("LAW", "Legal"),
    new KeyValuePair<string, string>("LEN", "Lending"),
    new KeyValuePair<string, string>("REL", "Real Estate"),
    new KeyValuePair<string, string>("RES", "Research"),
    new KeyValuePair<string, string>("OTH", "Other")
};

That also threw an error:

No overload for method ‘Add’ takes ‘1’ arguments

But the error pointed me back to my original idea: somehow I needed to use Add(), but how? And then it dawned on me: what the message is really telling me is that I was already using Add(), I just didn’t realize it! Since we use curly braces to denote Initializers, I decided to try that within the context of the parent Initializer to send parmameters to the Add method:

BusinessTypes = new Dictionary<string, string>()
{
    {"APP", "Appraisal"},
    {"GOV", "Government"},
    {"INS", "Insurance"},
    {"LAW", "Legal"},
    {"LEN", "Lending"},
    {"REL", "Real Estate"},
    {"RES", "Research"},
    {"OTH", "Other"}
};

This compiles fine and now I have successfully used an Object Initializer on a Dictionary<TKey, TValue> object. I was curious about why this works, so I hit the Google pavement and found this article on MSDN from October of 2006. In it, the author has this to say:

Our resolution to this is to refine our understanding of collection initializers a little bit. The list you provide is not a ?list of elements to add?, but a ?list of sets of arguments to Add methods?. If an entry in the list consists of multiple arguments to an Add method, these are enclosed in { curly braces }. This is actually immensely useful. For example, it allows you to Add key/value pairs to a dictionary, something we have had a number of requests for as a separate feature.

From previous text in the article, we find that any IEnumerable with a public Add method will behave this way. As such, we should be able to use this construct in almost all the generic Collection classes.

This is definitely useful, and yes I should have searched for a solution before I spent the entire 3 minutes trying to figure it out. But sometimes, I just like solving the puzzle.

Advertisements
Categories: .NET 3.5, C# 3.0
  1. mdonatas
    March 14, 2008 at 3:56 pm

    How about such solution thanks to extension methods magic?

  2. March 17, 2008 at 12:44 pm

    That is very interesting. At first I wondered why this would work when the built int .Add(x,y) method wouldn’t, but I figured it out.

    The reason is that .Add returns void, but mdonatas’s Extension Method returns the Dictionary object itself. I would be curious to see if there is a performance difference, but otherwise I think this is a good solution and shows one of the strengths of Extension Methods.

    Thanks mdonatas!

  1. No trackbacks yet.
Comments are closed.
%d bloggers like this: