我使用过模板字符串,从DB和/或文件文件中读取:
var template="Your order {0} has dispatched from {1}, ETA {2:HH:MM dd.MM.yyyy}";
然后使用string.Format(template, orderNo, warehouse, eta)
注入正确的值。
现在,做出了商业决策,将这些模板更改为使用更有意义的标记:
var template="Your order {orderNo} has dispatched from {warehouse}, ETA {eta:HH:MM dd.MM.yyyy}";
现在我不确定注入值的最佳方法是什么,考虑到例如eta
字段的格式是"硬编码"到模板(这样我们可以根据语言使用不同的DateTime
格式)
一个想法是将模板加载到StringBuilder
,将命名变量替换为{0}, {1}
等等,然后使用旧的string.Format
方法,但它不是真正可扩展,并在后面写下所有样板的痛苦。
var formatTemplate = new StringBuilder(template)
.Replace("{orderNo}", "{0}")
.Replace("{warehouse}", "{1}")
.Replace("{eta","{2")
.ToString();
return string.Format(template, orderNo, warehouse, eta)
有更好的方法吗?也许是一种将模板作为插值字符串读取的方法?该字符串是从外部源读取的,所以我不能简单地使用$"{marker}"
机制。
答案 0 :(得分:2)
请查看SmartFormat,它实际上可以执行您想要的操作。
(你说,你不使用用索引替换人类可读的名字)
他们的wiki示例:
String.Format按索引引用所有args:
String.Format("{0} {1}", person.FirstName, person.LastName)
Smart.Format更进一步,让您使用命名占位符:
Smart.Format("{FirstName} {LastName}", person)
事实上,Smart.Format支持多种表达式:
Smart.Format("{FirstName.ToUpper} {LastName.ToLower}", person)
工作示例要求将变量打包为匿名类型:
var formatted=Smart.Format(template, new { orderNo, warehouseName, eta })
返回正确,期望的结果,并正确替换标记。如果没有匿名类型,它似乎无法正常工作。
答案 1 :(得分:-1)
如果您的框架支持,您可以使用字符串插值: 看看这个: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/interpolated-strings
然后,您可以更新代码:
var orderNo = 1;
var warehouse = "Trinidad";
var template = $"Your order {orderNo} has dispatched from {warehouse}";