Voici une autre version de ce que je trouve ici: http://www.reddit.com/r/programming/comments/bodml/beef_up_params_in_c_5_to_solve_lambda_abuse/c0nrsf1
Toute solution à cela va impliquer la réflexion, qui est moins qu'idéale, mais voici son code avec quelques-uns des autres problèmes de performance majeurs résolus. (Pas d'erreur de vérification Ajouter si vous le souhaitez..):
1) utilise la réflexion d'exécution directe, pas de frais généraux DataBinder
2) Ne pas utiliser des expressions régulières, utilise un seul passage Parse et de l'état.
3) Ne convertit pas la chaîne en une chaîne intermédiaire, puis la convertit à nouveau au format final.
4) Alloue et concatène avec un seul StringBuilder au lieu de créer de nouvelles chaînes un par un et de les concaténer en de nouvelles chaînes.
5) Supprime la surcharge de la pile d'appel d'un délégué pour n opérations de remplacement.
6) En général est un seul passage qui mettra à l'échelle d'une manière relativement linéaire (encore un peu de coût pour chaque pilier recherche et la recherche de prop imbriqué, mais c'est ça.)
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();
}
+1. C'est intéressant, je n'ai jamais vu ça auparavant. On dirait que cela fonctionne bien avec les types anonymes. – RichardOD
Dans l'article lié, certains commentateurs sont préoccupés par les performances. Assurez-vous de voir si la performance est acceptable avant de l'utiliser. –
A dû aller avec la version de Scott puisque le FormatWith semble dépendre de System.Web. –