使用有意义的标记格式化字符串
Format string with meaningful markers
我曾经有一个模板字符串,从数据库和/或文本文件中读取:
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
字段的格式是 "hardcoded" 到模板中(这样我们可以根据语言使用不同的 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}"
机制。
请检查 SmartFormat 哪个实际上会做你想做的事。
(你说过,你不使用索引替换人类可读的名称)
来自他们 wiki 的示例:
String.Format 按索引引用所有参数:
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 })
returns 正确的、期望的结果,标记已正确替换。没有匿名类型,它似乎不起作用。
如果您的框架支持,您可以使用字符串插值:
看看这个:
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}";
我曾经有一个模板字符串,从数据库和/或文本文件中读取:
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
字段的格式是 "hardcoded" 到模板中(这样我们可以根据语言使用不同的 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}"
机制。
请检查 SmartFormat 哪个实际上会做你想做的事。
(你说过,你不使用索引替换人类可读的名称)
来自他们 wiki 的示例:
String.Format 按索引引用所有参数:
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 })
returns 正确的、期望的结果,标记已正确替换。没有匿名类型,它似乎不起作用。
如果您的框架支持,您可以使用字符串插值: 看看这个: 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}";