Using C# 3.0 Anonymous Types as Dictionaries
During a design meeting for a new feature in ASP.NET we had a requirement that a new method accept a dictionary of name/values pairs. An obvious solution is to have the method accept a parameter of type IDictionary (or its generic cousin):
public static string GetHtmlLink(string text, IDictionary<string, string> properties) {
...
}
While it looks nice and neat from the perspective of our function, the caller of this function has a real mess to deal with. Creating dictionaries is definitely somewhat of a pain. Since Dictionary<TKey, TValue> doesn't have an Add() method with one parameter you can't use C# 3.0's collection initializer syntax. This is some ugly code:
Dictionary<string, string> values = new Dictionary<string, string>();
values.Add("key1", "value1");
values.Add("key2", "value2");
values.Add("key3", "value3");
GetHtmlLink("Click me", values);
My proposal: Have the method accept a parameter of type object. Callers could pass in a type that has properties with the appropriate names and values. They can use C#'s object initializer syntax to save some space:
MyParams myParams = new MyParams { Key1 = "value1", Key2 = "value2", Key3 = "value3" };
GetHtmlLink("Click me", myParams);
However, there was the added work of defining the MyParams type. Admittedly, it wasn't that hard with C# 3.0's automatic properties, but I hate defining types that are used in only one place. If the user can pass in an arbitrary object with properties, why not let that object be of an anonymous type? Here's the final code:
GetHtmlLink("Click me", new { Key1 = "value1", Key2 = "value2", Key3 = "value3" });
Woah! We went from five lines of code with dictionaries to two lines of code with object initializers (minus the type definition), to just one line of code with anonymous types!
So what does the GetHtmlLink method look like, anyway? Download the code from the attachment. You can now use the two helpers like so:
Sample link: <%= HtmlHelpers.GetHtmlLink("My Site", new { @class = "someStyle", href = "http://www.example.org" })%>
<br />
Sample URL: <%= HtmlHelpers.GetUrl("http://www.example.org/search", new { query = "kitten's mittens", mode = "details" })%>
And it'll render this HTML:
Sample link: <a class="someStyle" href="http://www.example.org">My Site</a>
<br />
Sample URL: http://www.example.org/search?query=kitten's+mittens&mode=details
So, what do you think?
I'm obviously ignoring certain aspects of this technique such as performance. There are certainly ways to optimize the performance with some clever caching. Performance might not be an issue anyway, depending on where this code is used.
Have you come up with a novel way to use a new language feature that you'd like to share?