これが私がここで見つけた別のバージョンです:http://www.reddit.com/r/programming/comments/bodml/beef_up_params_in_c_5_to_solve_lambda_abuse/c0nrsf1
これに対する解決策にはリフレクションが含まれますが、これは理想的とは言えませんが、他の主要なパフォーマンスの問題のいくつかが解決された彼のコードを次に示します。(エラーチェックはありません。必要に応じて追加してください。):
1)DataBinderオーバーヘッドなしで、直接ランタイムリフレクションを使用します
2)正規表現を使用せず、シングルパスの解析と状態を使用します。
3)文字列を中間文字列に変換してから、再度最終形式に変換しません。
4)文字列をあちこちで更新して新しい文字列に連結するのではなく、単一のStringBuilderで割り当てて連結します。
5)n個の置換操作のデリゲートを呼び出すスタックオーバーヘッドを削除します。
6)一般に、比較的直線的にスケーリングするシングルパススルーです(各プロップルックアップとネストされたプロップルックアップにはまだいくらかのコストがかかりますが、それだけです)。
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();
}