Puoi pre-cache i nomi delle proprietà a cui sei interessato (cioè quelli con l'attributo Descrizione) e quindi utilizzare quelli per prendere solo i valori che ti interessa.
Ho violato un rapido esempio di questo, non è il codice più robusto, ma mostra l'idea generale (fa molte ipotesi sull'ordinamento) e ha recuperato gli attributi solo una volta.
(Modifica: realizzato che dovevamo chiamare GetProperties solo una volta per tutto).
var whitelist = typeof (DocumentTrackerChaseReport)
.GetProperties()
.Where(x => Attribute.IsDefined(x, typeof (DescriptionAttribute)));
var rows = things.Select(x => whitelist.Select(y => y.GetValue(x) ?? ""));
Questo ti darà un IEnumerable<IEnumerable<object>>
, o in altre parole, un elenco di righe e per ogni riga, un elenco di colonne (con il valore di ciascuna colonna che è un oggetto).
Potresti quindi iterare attraverso questo come segue (codice pseudo)
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
}