Scott Hanselman

The Weekly Source Code 12 - Back in Black Edition

January 8, '08 Comments [21] Posted in ASP.NET | Microsoft | Source Code
Sponsored By

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. I am a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by ORCS Web
Tuesday, January 08, 2008 8:59:50 PM UTC
re:Witty Alan S. did a great job on the TwitterNet library and the UI. I'm afraid to do much to the UI because the designer in VS2008 still balks at some of the XAML in Witty. Right now, XAML seems to be a lot like XHTML in terms of it's tolerability. If it can't parse it precisely, it just says "I can't do anything with this" and doesn't display anything. We're also trying to add functionality w/o cluttering up the interface and that's always a challenge.

Right now the biggest need in terms of refactoring is the way Witty makes web requests. There's a lot of !DRY there. We're also trying to work around some of the quirks of WPF.
Tuesday, January 08, 2008 9:49:23 PM UTC
Scott, I agree that regularly reading the source code of others (be it good or bad) can help anyone become a better developer. Thanks for showing us some great examples. I look forward to seeing more snippets like these in the future.
aggiekevin
Wednesday, January 09, 2008 4:28:53 AM UTC
This was really helpful. Actually its funny that many a times we learn more from reading some simple mistakes in others code. Many a times we can find those quirks in our's code and this helps a lot in improving the same.
Wednesday, January 09, 2008 4:30:15 AM UTC
Hi Scott,

You haven't blogged about DLR and IronRuby / IronPython so far.

Kindly blog at length covering few codes, with the above dynamic languages that are coming our way in near future.

We do not see any discussion on this powerful languages, which is really needed.

Few words on Dynamic VB shall be welcomed too. I was happy to see the discussions on PHP and DLR have started. The DLR seems to be the future, and all dynamic languages shall one by one step into DLR.

Pl. spread the requested news and current stage of their progress.

Thanks
Wednesday, January 09, 2008 4:43:23 AM UTC
Hi Scott,

Can you cover an interesting topic like.... " Asp.Net MVC on the DLR with IronRuby. "

Such a topic is not seen anywhere discussed, and will bring few smiles on Rubyists, who are working on other platforms and are just tied up with ROR as an only solution.

Let the Ruby Community know, what coming their way soon.

BTW... are we getting any Beta versions of dynamic languages in near future. DLR and Dynamic lamguages were announced at last MIX 2007 and the New MIX 2008 is round the corner ( March 2008 )

Thanks
Wednesday, January 09, 2008 9:54:44 AM UTC
Hi Scott,

I recently wrote about how I like to do Dictionaries in C#3.0. I created an extension method which converts an anonymous type to a dictionary, so you can do this:

var myObject = new { Name = “Frank”, Age = 5 };
var dict = myObject.ToPropertyHash();


Here, dict would be a dictionary containing keys "Name" and "Age".

The full post is on my blog at http://richardbushnell.net.

Love the series, btw.
Wednesday, January 09, 2008 2:33:11 PM UTC
Hey Now Scott,
I like how you state this is an infinite series. I've learned from & enjoyed these posts.
HanselMinutes Fan,
Catto
Wednesday, January 09, 2008 6:24:07 PM UTC
Hi Scott,

I didn't spend much time on that particular method. It is a quick modification of http://twitter.pbwiki.com/RelativeTimeScripts to match how Twitter display the relative time on the twitter.com when they deprecated the relative_created_at attribute in the API.
Wednesday, January 09, 2008 8:17:24 PM UTC
I'd love to see some examples of testing code, including fit/fitnesse or Watin/Selenium.
Dauchande
Thursday, January 10, 2008 3:36:50 AM UTC
MyParams myParams = new MyParams { Key1 = "value1", Key2 = "value2"};
GetHtmlLink("Click me", myParams);
is not something new, no need to go far to see very elegant code like this, just look at the code produced by the form designer whenever say a combobox is used with items populated by hand from the property pages (F4).
ArthurZ
Thursday, January 10, 2008 4:14:29 AM UTC
ArthurZ, that seems like Array initalization, which is a different thing:

this.comboBox1.Items.AddRange(new object[] {
"dsfs",
"sdfsdf",
"sdfsf"});
Thursday, January 10, 2008 5:15:45 AM UTC
IronRuby, actually check the screencasts category of this blog, I did a whole hour long screencast on MVC with the DLR two months ago. However, I'll do some more DLR content soon.
Thursday, January 10, 2008 2:46:45 PM UTC
Hey Scott,

I thought you might be able to shorten the Array initialization a bit more now. I know you can do this (note the missing "new string[]"):

string[] myArray = {"one", "two", "three"};
this.comboBox1.Items.AddRange( myArray );

But you can't do this:
this.comboBox1.Items.AddRange( {"one", "two", "three"} );


But you can do this:
this.comboBox1.Items.AddRange(
new[] {"one", "two", "three"}
);


At least it's a little nicer than before.
Saturday, January 12, 2008 5:08:38 AM UTC
Man, I still don't get this obsession with using anonymous types (and a usually hidden but obviously giant pile of slow reflection) as dictionaries, all to get a better initializer syntax. You can cook up awesome dictionary initialization syntax and avoid none of the reflection tax, without going over the edge of the class design guidelines (though admittedly getting near to the edge). I've commented more over on Eilon's post, but the syntax basically ends up looking like (I'll use the 3.5 syntax here, "D" is a utility function that gets things started, you can call it whatever you want)

var dictionary = D<string, string>()
["Key1", "value1"]
["Key2", "value2"]
["Key3", "value3"];

Implementation is left as a weekend exercise for the reader. ;)
Jeremy Gray
Saturday, January 12, 2008 5:18:37 AM UTC
Whoops. Forgot to add something... If you use the "var" syntax, you need to do a bit mor typing before the semi-colon, but explicitly declaring "dictionary" as IDictionary<string, string> will also do the trick.
Jeremy Gray
Thursday, January 24, 2008 6:52:53 PM UTC
I agree with Jeremy, what Eilon did to anonymous types to get around using Dictionaries is exactly what I was afraid would happen when anonymous types were introduced in C#. People start thinking that C# is a dynamic language and that anonymous types and object/collection initializers are the cure to all their syntax ills. Guess what? C# is NOT a dynamic language, and writing code like that is creating a performance and maintenance nightmare just waiting to ruin your day. I wish the C# language team had put more thought into this rather than trying to stuff dynamic language features into a non-dynamic language. As it is, I will just have to keep a sharp eye out for C# code written by people who think they are writing in Ruby.
Sunday, January 27, 2008 3:31:56 AM UTC
Hey Scott,
Nice article, actually i got this link on Start page of Visual studio - and it sounds great idea and column.

one small suggestion
I am from India, and y`day we celebrated Republic day (26th Jan) in India and when i opened this link and went down i got the same day !!!!!!! (26 jan 2008)...

may be they can embad the feature of proper time zone rendering

--- thank
Pradeep
Wednesday, January 30, 2008 9:38:20 AM UTC
I couldn't agree more with Jeremy and David.

I'm no Ruby person, in fact never even touched it so I can't say much about the yearn to program in the style of a dynamic language, but looking at it from a .net perspetive I can see how dangerously wrong this is. Unless someone can prove that the reflection engine has improved its performance greatly in 3.5 to cater for its potential more frequent due to the introduction of these C# 3.0 features, then I don't see how anyone could fathom using it so loosely. Perhaps it's not so much of a problem for desktop applications, but I'd stay away from freely using reflection like this in an asp.net app for instance.

We all want clearer code, but I think performance should never take a hit just so that we can have five lines of code transformed into one with no apparent gain. Unless there is something specific about the code that will indeed become a critical maintenance issue down the road and there is no other way, but to refactor it using extreme measures that affect the application in one way or another.

There is always a trade-off and that's what everyone should keep in mind when trying to do pretty things. (although I must admit it is quite pretty!)
Wednesday, February 13, 2008 5:48:37 AM UTC
Hi,I am Shiva i'm new to this coding andnew to this job,i want to be perfect in coding how can I.Give me any reference about any site which helps me with Basics
Shiva
Saturday, February 23, 2008 3:29:34 PM UTC

Sir;

i want to create one my own small site on my home. Such that from that page i can send mails to another account.

thre should be option of

from id :- textbox
to id :- textbox
subject :- textbox
message :- textbox
send

thnks u
raman singla
raman singla
Wednesday, March 05, 2008 6:57:09 PM UTC
I find it extremely difficult to believe that you were reading code while changing diapers. You must have four hands because it takes both my hands and sometimes a foot (to open the diaper genie) to change my son's diaper.
Louis
Comments are closed.

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.