Ecco un'altra versione di questo che ho trovato qui: http://www.reddit.com/r/programming/comments/bodml/beef_up_params_in_c_5_to_solve_lambda_abuse/c0nrsf1
Qualsiasi soluzione a questo sta per coinvolgere la riflessione, che non è l'ideale, ma ecco il suo codice con alcuni degli altri importanti problemi di prestazioni risolti. (Verifica nessun errore Aggiungi, se vuoi..):
1) utilizza la riflessione di esecuzione diretta, senza DataBinder sovraccarico
2) Non utilizzare le espressioni regolari, utilizza un parse single-pass e stato.
3) Non converte la stringa in una stringa intermedia e quindi la converte nuovamente nel formato finale.
4) Assegna e concatena con un singolo StringBuilder invece di creare nuove stringhe su tutto il luogo e concatenarle in nuove stringhe.
5) Rimuove il sovraccarico dello stack per chiamare un delegato per n operazioni di sostituzione.
6) In generale, è un singolo passaggio che si scala in modo relativamente lineare (ancora un certo costo per ogni ricerca prop e ricerca prop nidificati, ma questo è tutto.)
public static string FormatWith(this string format, object source)
{
StringBuilder sbResult = new StringBuilder(format.Length);
StringBuilder sbCurrentTerm = new StringBuilder();
char[] formatChars = format.ToCharArray();
bool inTerm = false;
object currentPropValue = source;
for (int i = 0; i < format.Length; i++)
{
if (formatChars[i] == '{')
inTerm = true;
else if (formatChars[i] == '}')
{
PropertyInfo pi = currentPropValue.GetType().GetProperty(sbCurrentTerm.ToString());
sbResult.Append((string)(pi.PropertyType.GetMethod("ToString", new Type[]{}).Invoke(pi.GetValue(currentPropValue, null), null)));
sbCurrentTerm.Clear();
inTerm = false;
currentPropValue = source;
}
else if (inTerm)
{
if (formatChars[i] == '.')
{
PropertyInfo pi = currentPropValue.GetType().GetProperty(sbCurrentTerm.ToString());
currentPropValue = pi.GetValue(source, null);
sbCurrentTerm.Clear();
}
else
sbCurrentTerm.Append(formatChars[i]);
}
else
sbResult.Append(formatChars[i]);
}
return sbResult.ToString();
}
fonte
2013-02-18 22:23:48
+1. È interessante, non l'ho mai visto prima. Sembra che funzioni bene con i tipi anonimi. – RichardOD
Nell'articolo collegato alcuni commentatori sono preoccupati per le prestazioni. Assicurati di vedere se le prestazioni sono accettabili prima dell'uso. –
Doveva andare con la versione di Scott poiché FormatWith sembra dipendere da System.Web. –