The Weekly Source Code 12 - Back in Black Edition
It's been a while since the last Weekly Source Code, but I have the holidays and the preponderance of baby poop as a fine formal excuse. I'm back from Paternity now and the Source Code will keep coming weekly as originally promised.
If you're new to this, each week I post some snippets of particularly interesting (read: beautiful, ugly, clever, obscene) source and the project it came from. This started from a belief that reading source is as important (or more so) as writing it. We read computer books to become better programmers, but unless you're reading books like Programming Pearls, you ought to peruse some Open Source projects for inspiration.
And so, Dear Reader, I present to you the twelfth in a infinite number of posts of "The Weekly Source Code." Here's some source I was reading while changing diapers.
- Looking for applications that use WPF? They are out there and they don't always have "juicy buttons" and scream "I was written in WPF." Sometimes they are just clean, simple and functional. Witty is a Twitter (chat-esque) client written in WPF, a technology I have yet to fully grok.
This little app has a simple Twitter Client Library that includes inside it a TinyUrl maker. (Google better buy TinyUrl or the whole web might get link rot) Sometimes it's fun to read source for the comments, but it's also cathartic to read code that you didn't write and say to yourself, "hey, this could use some refactoring." Perhaps a good time for you to offer to help an Open Source Project.
This example is the most trivial chunk of code in Witty, but somehow it made me smile. Regardless, the MainWindow of Witty also had some interesting stuff, particularly the background fetching of data. It's definitely easier than WinForms.public void UpdateRelativeTime() { DateTime StatusCreatedDate = (DateTime)dateCreated; TimeSpan ts = new TimeSpan(DateTime.Now.Ticks - StatusCreatedDate.Ticks); double delta = ts.TotalSeconds; string relativeTime = string.Empty; if (delta == 1) { relativeTime = "a second ago"; } else if (delta < 60) { relativeTime = ts.Seconds + " seconds ago"; } else if (delta < 120) { relativeTime = "about a minute ago"; } else if (delta < (45 * 60)) { relativeTime = ts.Minutes + " minutes ago"; } else if (delta < (90 * 60)) { relativeTime = "about an hour ago"; } else if (delta < (24 * 60 * 60)) { relativeTime = "about " + ts.Hours + " hours ago"; } else if (delta < (48 * 60 * 60)) { relativeTime = "1 day ago"; } else { relativeTime = ts.Days + " days ago"; } RelativeTime = relativeTime; } - Folks are poking at C# 3.0 trying to get lambdas and anonymous type declarations to feel and act like Ruby hash table declarations. It'll be interesting to see if Anders is already on top of this. I wonder if he and Matz hang out? If I invented a language, I'd make a really exclusive clubhouse. ;)
Eilon shows the difference between Dictionaries and anonymous types in his proposal:
- 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!
- Bill asks for better Dictionary Initializers, and Alex does it with lambdas in his post, giving him this clean syntax, and PhilHa weighs in with his thoughts. Bill says "Your inner Rubyist is nodding with approval."
Dictionary<string, object> items = Hash<object>(Name => "alex", TargetType => typeof(Uri), Id => 10);
Assert.AreEqual(10, items["Id"]); - If you're looking to do small GUI applications, you might take a moment to look at "Shoes" the tiny Ruby UI Tookit. Why? Well, if you're an old WinForms or new WPF guy like myself, (or an old Java guy, also like myself) it's helpful to other perspectives on what a Domain Specific Language for UI might look like. The sample source is here.
Here are four different snippets in four different language that show a single button with a click event handler that shows a message.
Here's the same thing in Shoes. Note that the documentation for Shoes is available as a Ransom Note. The creator never uses the acronym "GUI" in the docs or materials, but prefers to think of Shoes as a "toy." It's a pretty near toy, take a look at the 2D animation examples.Shoes.app { button("Press Me") { alert("You pressed me") } } -
Rob (and lots of other folks) are exploring what UserControls look like in an ASP.NET MVC world. He says "Your UserControl can be one of two things: A granular bit of UI that renders information passed from a Controller [or] a granular bit of UI that renders information from an application-wide data source." He calls them a "Viewlet" and offers these helper methods:
Rendering a ViewUserControl
The MVC Toolkit has a nice method called “RenderUserControl()” that allows you to process your ViewUserControl and output it’s result inline:<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”)%>
If the ViewUserControl is typed (say ViewUserControl<MyControllerData>), then it’s ViewData object will be filled for you, and your ViewPage and rendered control will share the same data.
If you want to be explicit about it, you can do that as well, specifying the data to pass:
<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”,ViewData.Users)%>
Finally, if you need to set properties on the ViewUserControl, you can do that as well by passing in an anonymous type:
<%=Html.RenderUserControl(“~/UserControls/UserList.ascx”,ViewData.Users, new {GroupID=2})%>
Enjoy, and keep reading code!
About Scott
Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.
About Newsletter





