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.
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; }
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!
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!
Dictionary<string, object> items = Hash<object>(Name => "alex", TargetType => typeof(Uri), Id => 10); Assert.AreEqual(10, items["Id"]);
Shoes.app { button("Press Me") { alert("You pressed me") } }
<%=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!
var myObject = new { Name = “Frank”, Age = 5 };var dict = myObject.ToPropertyHash();
string[] myArray = {"one", "two", "three"}; this.comboBox1.Items.AddRange( myArray );
this.comboBox1.Items.AddRange( {"one", "two", "three"} );
this.comboBox1.Items.AddRange( new[] {"one", "two", "three"} );
Ads by The Lounge