February 2009 - Posts

Free Microsoft Events

Microsoft is planning a full-day of free presentations at it's Southfield, Michigan office on March 31st.

ArcReady: Architecting for the Cloud, 9:00am – 11:45am, Register

MSDN Events Unleashed (2 Sessions): (1) VS2008 Debugging and (2) Developing for Windows Mobile Devices, 1:00pm – 3:00pm, Register

TechNet Events Unleashed: Windows Server 2008, 3:00pm – 5:00pm, Register

Not only are these events free, but there will be prizes available for attendees (VS2008, Vista, Office, Books, etc…).

Technorati Tags: ,,,,
Posted by PSteele | with no comments
Filed under: ,

The Essence of Open Source

While doing catch-up reading on the Rhino.Mocks group on Google, I came across this thread about a problem someone was having with Rhino.Mocks.  What I thought was cool was the responsiveness of Ayende (the creator of Rhino.Mocks).  And I'm not singling him out (I hear he hates being put on a pedestal), but I'm highlighting the generic responsiveness that you are more likely to get with an open source project.  Here's a breakdown of the timeline:

8:12 PM – Original question posted about the issue.

8:38 PM – Ayende asks for clarification on the exact issue.

9:55 PM – Original poster shows sample code highlighting the issue.

11:02 PM – At the request of Ayende (@ 10:13 PM), the original poster creates a failing test case that shows the issue in Rhino.Mocks

11:34 PM – The bug is fixed and in the repository for everyone to download and use.

Slightly over 3 hours from bug report to resolved issue.  That's pretty damn cool!  In many commercial applications, it can take 3 hours just to acknowledge your support request.

Technorati Tags: ,,
Posted by PSteele | with no comments
Filed under:

Getting Func-y with Lambdas

Let's say we've got some information stored somewhere (database, XML, file – it doesn't matter) about individuals.  For simplicity, let's look at a class that represents this data:

   1: class Person
   2: {
   3:     public string FirstName { get; set; }
   4:     public string LastName { get; set; }
   5:     public string EmailAddress { get; set; }
   6:  
   7:     public static Person FindByEmailAddress(string emailAddress)
   8:     {
   9:         // implementation omitted
  10:     }
  11:  
  12:     public void Save()
  13:     {
  14:         // implementation omitted
  15:     }
  16: }

We've got some exported CSV data that needs to be merged into this set of data.  However, the information from the CSV file has multiple email address' per person.  Here's the class that represents each row of CSV data:

   1: class CSVData
   2: {
   3:     public string FirstName { get; set; }
   4:     public string LastName { get; set; }
   5:     public string HomeEmail { get; set; }
   6:     public string WorkEmail { get; set; }
   7: }

Some people in the CSV data will have only a home email, some will have only a work email, and some will have both.  I can easily get a couple of lists that contain the people with email address' defined via LINQ (note: the implementation of LoadCSVData is not important here):

   1: IList<CSVData> csvData = LoadCSVData();
   2: var peopleWithHomeEmail = from c in csvData where c.HomeEmail.Length > 0 select c;
   3: var peopleWithWorkEmail = from c in csvData where c.WorkEmail.Length > 0 select c;

Now I want to loop through each list, see if the email address is already in our current data store and add ones that are not.

   1: UpdateEmails(peopleWithHomeEmail);
   2: UpdateEmails(peopleWithWorkEmail);

A simple implementation of UpdateEmails might look like this:

   1: private void UpdateEmails(IEnumerable<CSVData> list)
   2: {
   3:     foreach (var dataItem in list)
   4:     {
   5:         Person person = Person.FindByEmailAddress(dataItem.HomeEmail);
   6:         if (person == null)
   7:         {
   8:             person = new Person()
   9:             {
  10:                 FirstName = dataItem.FirstName,
  11:                 LastName = dataItem.LastName,
  12:                 EmailAddress = dataItem.HomeEmail
  13:             };
  14:             person.Save();
  15:         }
  16:     }
  17: }

The obvious problem with this is that it always accesses the HomeEmail address field from the CSVData.  What's going to happen when I pass "peopleWithWorkEmail" to this method?  Not good.

Delegates To The Rescue

This is the perfect place for a delegate. We'd like to have some function that accepts a CSVData object and returns a string – either home email or work email:

   1: private delegate string GetEmailAddress(CSVData data);

Now we can re-write our UpdateEmails method to accept a delegate that will determine which email address we'll grab:

   1: private void UpdateEmails(IEnumerable<CSVData> list, GetEmailAddress getEmail)
   2: {
   3:     foreach (var dataItem in list)
   4:     {
   5:         Person person = Person.FindByEmailAddress(getEmail(dataItem));
   6:         if (person == null)
   7:         {
   8:             person = new Person()
   9:             {
  10:                 FirstName = dataItem.FirstName,
  11:                 LastName = dataItem.LastName,
  12:                 EmailAddress = getEmail(dataItem)
  13:             };
  14:             person.Save();
  15:         }
  16:     }
  17: }

Thanks lambdas, we can make the calling code very clean:

   1: UpdateEmails(peopleWithHomeEmail, p => p.HomeEmail);
   2: UpdateEmails(peopleWithWorkEmail, p => p.WorkEmail);

A very clean solution.  Except…

Delegate Maintenance

The only issue with this is now we have a delegate sitting around just for this simple lambda expression.  At some point in time, we may want to do some date calculations from data found inside CSVData.  If we had multiple dates to pick from (like multiple emails in this situation), we may have to create another delegate that accepts a CSVData and returns a DateTime.  What we need is a generic way of defining a method that accepts some data type(s) and returns a specific data type (note emphasis on generic!).

Since this is such a common scenario, Microsoft has pre-defined a bunch of generic delegates that do exactly what we need.

Getty Func-y

Here's what you can use from System.Core:

Func<TResult> – This delegate takes no parameters and simply returns an object of type TResult

Func<T, TResult> – Just like Func<TResult>, but this one accepts a single parameter (T).  This is exactly the situation we have in our example.

Microsoft also defines three other Func<> delegates – one that accepts 2 parameters, one that accepts 3 and finally, one that accepts 4.  Anything more than four and you'd have to define your own Func<> delegate.

We can now get rid of our GetEmailAddress delegate and replace it with a Func<CSVData, string> (which is the exact same signature – a method that accepts a CSVData and returns a string):

   1: private void UpdateEmails(IEnumerable<CSVData> list, Func<CSVData, string> getEmail)

Our calling code doesn't need to change at all.  We're still using the same signature, so the C# compiler can infer the delegate usage for us and generate the anonymous method.  Yeah!

What about a Union

Why not use a Union along with an anonymous type?  This is definitely an idea to consider.  We could do this:

   1: var home = from c in csvData where c.HomeEmail.Length > 0 select new { FirstName = c.FirstName, LastName = c.LastName, Email = c.HomeEmail };
   2: var work = from c in csvData where c.WorkEmail.Length > 0 select new { FirstName = c.FirstName, LastName = c.LastName, Email = c.WorkEmail };
   3: var completeList = home.Union(work);

Now we have a single list which contains everything we need.  The anonymous type contains a single "Email" field which will contain either the HomeEmail or the WorkEmail.  The only issue with this is that you can't pass anonymous types to methods – and I wanted the email update loop to be it's own method.

And yes, I could have created an actual type instead of an anonymous type – but then I would have an extra type laying around just to aggregate the CSVData.  Kind of sounds like the reason I got rid of the delegate…  :)

Technorati Tags: ,,
Posted by PSteele | 3 comment(s)
Filed under:

SRT: "Best of Best of Michigan Award"

Right now, SRT co-founders Bill Wagner and Dianne Marsh are in Troy at an awards breakfast.  SRT (along with a bunch of other companies) has received Corp! Magazine's "Best of the Best Michigan Business" award.

Congratulations to Bill and Dianne for building such a great company to work for!  This truly is the best job and best environment I've been in professionally.  And thanks to all of my fellow SRT employees who I don't get to see nearly as often as I'd like (the downside of living 2 hours away from the main office!).

Technorati Tags: ,,
Posted by PSteele | with no comments
Filed under:

ASP.NET MVC Goodness!

Last week at AADND, I gave a presentation on MonoRail, the Castle Project's MVC implementation on ASP.NET.  The MVC pattern is so popular (and productive!) among web developers, I'm sure you're aware that Microsoft is working on ASP.NET MVC – which is now up to RC1.

If you're interested in learning more about ASP.NET MVC, Josh Holmes has a great series on building a simple photo gallery in ASP.NET MVC.  It starts with the basics and adds more and more features with each post.  Check it out:

Technorati Tags: ,
Posted by PSteele | 1 comment(s)
Filed under: ,

Silverlight: Checking Checkboxes

I was playing around with Silverlight a little bit today and noticed something with the Checkbox UI element.  It has both a "Checked" and "Unchecked" event.  These obviously correspond to when the checkbox becomes checked or unchecked.  This is in contrast to the WinForms checkbox which simply has a CheckChanged event.  Interesting…

Technorati Tags: ,,
Posted by PSteele | 1 comment(s)
Filed under: ,

LINQ: Grabbing a single element

Since I've seen code like this before and am also guilty of writing code like this, I thought I'd blog about an easier way to grab a single element from a LINQ query that Bill Wagner told me about at last night's AADND meeting.

Consider the following class:

   1: public class Person
   2: {
   3:     public string Name { get; set; }
   4:     public int Age { get; set; }
   5:     public bool Leader { get; set; }
   6: }

And let's load up some sample data:

   1: Person[] people = new Person[] {
   2:     new Person { Name = "Blue", Age = 25, Leader = true },
   3:     new Person { Name = "Gold", Age = 16, Leader = false },
   4:     new Person { Name = "Red", Age = 27, Leader = false },
   5:     new Person { Name = "Green", Age = 14, Leader = false}
   6: };

Now what we could do to find the leader (the assumption is that there is always only one leader):

   1: Person leader = people.Where(p => p.Leader == true).ToArray()[0];

The result of the people.Where() is an IEnumerable<Person>.  And you can't just index the first element of that – so you convert it to an array and index that instead.

LINQ provides two methods to perform this type of query without the need of having an intermediate array -- "First" and "Single":

   1: Person leader2 = people.First(p => p.Leader == true);
   2: Person leader3 = people.Single(p => p.Leader == true);

The difference between the two is that First grabs the first item it finds.  The Single method expects only a single matching item and will throw an exception if it finds more than one.  In this case, there is only one Person in the array that has Leader set to true so both of these lines of code produce the same result.

However, in the situation below:

   1: Person firstChild1 = people.First(p => p.Age < 18);
   2: Person firstChild2 = people.Single(p => p.Age < 18);

The first line will succeed.  The second line will fail since there are two people that are under 18.

Technorati Tags: ,

Posted by PSteele | 4 comment(s)
Filed under:

Jay Harris: Macro Sleuth

Jay Harris came to speak at GANG last month (great CI talk, by the way!).  After plugging in his laptop to the projector he glanced at the screen – he was checking if the font size was okay.  Seemingly not pleased, I saw him tap a few keys on the keyboard and the font just grew!  It was like zoom-in/zoom-out in Firefox.  He didn't mess around deep inside menus – just a couple of keystrokes and the font was bigger!

We all asked him how he did that and after he told us, we all said "You've got to blog that!"  And now he has.  Thanks Jay!

Posted by PSteele | with no comments
Filed under:

Properties vs. Attributes

One of my favorite bloggers, Eric Lippert, has a great post on the "properties vs. attributes" question.

...classes and structs and interfaces and whatnot are mechanisms that we use to implement model elements that represent the desired semantics in a manner that we as software developers find amenable to our toolsBut let's be careful to not confuse the thing being modeled with the mechanisms we use to model it.

Technorati Tags: ,,
Posted by PSteele | with no comments
Filed under:
More Posts