You can pre-cache the names of the properties that you are interested in (i.e. the ones with the description attribute) and then use those to only grab the values you are interested in.
I've hacked together a quick example of this, it's not the most robust code but it shows the general idea (makes a lot of assumptions about ordering) and only fetched the attributes once.
(Edit: realised we only needed to call GetProperties once for everything).
var whitelist = typeof (DocumentTrackerChaseReport)
.GetProperties()
.Where(x => Attribute.IsDefined(x, typeof (DescriptionAttribute)));
var rows = things.Select(x => whitelist.Select(y => y.GetValue(x) ?? ""));
This will give you an IEnumerable<IEnumerable<object>>
, or in other words, a list of rows and for each row, a list of columns (with the value of each column being an object).
You could then iterate through this as follows (pseudo code)
foreach (var header in whitelist) {
// print column of header row
}
foreach (var row in rows) {
foreach (var col in row) {
// print an individual cell
}
// break for a new row
}