これについて考えた後、私が実際に望んでいたことは、String.Format() が引数として IDictionary を取り、インデックスの代わりに名前を使用してテンプレートを記述できることであることに気付きました。
多くの可能なキー/値を持つ文字列置換の場合、インデックス番号は判読できない文字列テンプレートになります。場合によっては、どのアイテムがどの番号を持つのかさえわからない可能性があるため、次の拡張を思いつきました:
https://gist.github.com/896724
基本的に、これにより、数値の代わりに名前を使用して文字列テンプレートを使用し、配列の代わりに辞書を使用して、String.Format() の他のすべての優れた機能を使用できるようになり、必要に応じてカスタム IFormatProvider を使用できるようになります。精度、長さなど、すべての通常の書式設定構文の使用。
String.Formatのリファレンス マテリアルで提供されている例は、多くの番号付きアイテムを含むテンプレートが完全に判読不能になる方法の優れた例です。この例を移植して、この新しい拡張メソッドを使用すると、次のようになります。
var replacements = new Dictionary<String, object>()
{
{ "date1", new DateTime(2009, 7, 1) },
{ "hiTime", new TimeSpan(14, 17, 32) },
{ "hiTemp", 62.1m },
{ "loTime", new TimeSpan(3, 16, 10) },
{ "loTemp", 54.8m }
};
var template =
"Temperature on {date1:d}:\n{hiTime,11}: {hiTemp} degrees (hi)\n{loTime,11}: {loTemp} degrees (lo)";
var result = template.Subtitute(replacements);
誰かが指摘したように、あなたが書いているものを高度に最適化する必要がある場合は、このようなものを使用しないでください.ループで何百万もの文字列をこのようにフォーマットする必要がある場合、メモリとパフォーマンスのオーバーヘッドが大きくなる可能性があります.
一方、読みやすく、保守しやすいコードを書くことに関心がある場合、そしてたとえば一連のデータベース操作を行っている場合、大まかに言えば、この関数によって大きなオーバーヘッドが追加されることはありません。
...
便宜上、辞書の代わりに匿名オブジェクトを受け入れるメソッドを追加しようとしました。
public static String Substitute(this String template, object obj)
{
return Substitute(
template,
obj.GetType().GetProperties().ToDictionary(p => p.Name, p => p.GetValue(obj, null))
);
}
なんらかの理由で、これは機能しません。new { name: "value" }
拡張メソッドのような匿名オブジェクトを渡すと、そのメソッドの IDictionary バージョンが最適であるというコンパイル時のエラー メッセージが表示されます。それを修正する方法がわからない。(誰でも?)