IEnumerable<DataPair<object, String>> RowKeysWithHeaders
Now, let's say I'm using the data returned by the query I mentioned yesterday, which will only include dates for which there are TrackedTime entries, but I want to display all dates within a given date range, and simply leave cells empty if there are no entries for those dates. Furthermore, I want to specify how the dates are formatted. I could create a list of date/String pairs to use as row keys with headers, like this:
But that would be kind of wasteful, wouldn't it? It would mean creating an entire List of dates, when all I need is to print a bunch of consecutive dates--something I should be able to do mathematically on the fly.
List<DataPair<object, String>> dateHeaders = new List<DataPair<object, String>>();
A more efficient way would be to create an IEnumerable class (and an accompanying IEnumerator class) that know how to iterate across dates. But that's a lot more work and a lot more code for something that should be relatively simple.
Thanks to the yield operator, there is a better way. This simple method:
... will create an enumerable object that does exactly what I need it to, without the need for any extra classes or anything. Here's how I use it:
public static IEnumerable<DateTime> DaysInRange(DateTime startDate, DateTime endDate)
this.ReportTableDisplay1.RowKeysWithHeaders = from d in DaysInRange(startDate, endDate)
It can also be used to highlight one of the dangers of accepting IEnumerable arguments. Since I literally have no idea how expensive it might be to iterate over a given IEnumerable, I need to make sure my ReportTableDisplay class only iterates over the RowKeysWithHeaders once. Otherwise I could end up creating who-knows-how-many copies of exactly the same DataPair without even realizing it. Just think how that would turn out if I was using a truly expensive IEnumerable--one whose IEnumerator begins by accessing data from over the Internet, for example!