Continuing with the general theme of Func<>, Action<> and generics here is a nice little trick to replace long but simple switch statements. Often in your code you will find statements like this:
switch (category)
{
case Category.Articles:
DisplayBox.Text = "There are " + GetArticleCount(user) + " articles";
break;
case Category.Posts:
DisplayBox.Text = "There are " + GetPostCount(user) + " posts";
break;
case Category.Comments:
DisplayBox.Text = "There is " + GetCommentCount(user) +
" comments on " + GetPostCount(user) + " posts";
break;
case Category.Votes:
DisplayBox.Text = "Found " + GetVoteCount(user) + " recent votes";
break;
case Category.Videos:
DisplayBox.Text = "Found " + GetVideoCount(user) + " submitted videos";
break;
}
It’s pretty ‘wordy’ for a start, and crucially we are duplicating the DisplayBox.Text = bit 5 times which is not ideal. Wouldn’t it be nice to make the code shorter, clearer and better? It is really almost too easy! Define a new typed dictionary with Category as a key and a Func<> as the value:
var categoryMap = new Dictionary<Category, Func<User, string>>
{
{ Category.Articles, u => "There are " + GetArticleCount(u) + " articles"},
{ Category.Posts, u => "There are " + GetPostCount(u) + " posts" },
{ Category.Comments, u => "There is " + GetCommentCount(u) +
" comments on " + GetPostCount(u) + " posts" },
{ Category.Votes, u => "Found " + GetVoteCount(u) + " recent votes" },
{ Category.Videos, u => "Found " + GetVideoCount(u) + " submitted videos" }
};
The Func<User, string> declaration defines an inline method taking a single User argument and returning a string. All we then need to do is check we have a matching Category key in the map and then execute the matching function:
if (categoryMap.ContainsKey(category))
DisplayBox.Text = categoryMap[category](user);
This is overall more than a third less lines, and your intent is more clearly described.
Update: Dave Van den Eynde pointed out the issue of the overhead involved setting up a dictionary. I ran some tests, which you can read about in the comments, the result being there is a slight overhead using this technique (0.003ish of a millisecond) when run a single time. If this code exists in a loop however, define the dictionary outside of your loop and it can actually be very slightly faster (1 millisecond in 10,000 repetitions) than using switch. I thought it was worth pointing out the pros and cons here for those who don't read comments.
Happy coding!
Did you find this post useful or interesting? I'd be really grateful if you could return the favour by clicking this google link:
f18957ab-4974-4df1-8201-29ef35e9ba92|2|5.0