通常,当我们有一个模板文件和一些要运行的文本替换时,我们创建一个Dictionary<string,string>
看起来像这样的:
Dictionary<string,string> substitutions = new Dictionary<string, string>
{
{"{firstname}", customer.FirstName },
{"{lastname}", customer.LastName },
{"{address}", "your address" },
{"{siteurl}", _siteUrl },
};
if (customer.Address != null)
{
substitutions["{address}"] = customer.GetAddress();
}
等等。然后我们可以做类似的事情:
email.Body = substitutions.Aggregate(template,
(current, sub) => current.Replace(sub.Key, sub.Value));
获取替换的模板。
我今天遇到了一种情况,我需要确保换人以特定的顺序进行。
现在我可以确保它们Dictionary
以正确的顺序放入,并希望它们枚举的任意顺序保持该顺序 - 我从未见过 aDictionary
以其他顺序枚举,但 an 的顺序ICollection
不是保证。
所以让我感到震惊的是,做这样的事情会很有用(在哪里i++
被用作“任何价值”的占位符:
SomeCollection<string,string,int> substitutions
= new SomeCollection<string, string, int>
{
{"{firstname}", customer.FirstName, i++ },
{"{lastname}", customer.LastName, i++ },
{"{address}", "your address", i++ },
{"{siteurl}", _siteUrl, Int32.MaxValue }, // this should happen last
};
if (customer.Address != null)
{
substitutions["{address}"] = customer.GetAddress();
}
我可以通过IComparer
某种方式对int
价值进行排序。
但后来我试图弄清楚如何制作这样一个集合,并且在尝试编写由 a 支持的东西失败之后Dictionary<string, Tuple<int, string>>
,我决定我的代码的优雅不值得它给我带来的压力(考虑到最后期限等) on) 并且我可以在通话.Replace("{siteurl}", _siteUrl)
结束时添加Aggregate
但让我烦恼的是,我已经放弃了本来可以很优雅的东西。我遇到的问题(除了试图让 aDictionary<string, Tuple<int, string>>
成为一个实现ICollection<KeyValuePair<string,string>>
并弄清楚如何实现这些GetEnumerator
方法,同时尽量不强调截止日期)是我想要以下内容:
- 使用上面的对象初始化器语法简单地声明它的能力。
- 通过键获取和设置成员的能力(因此支持 a
Dictionary<string, Tuple<int, string>>
)。 - 有一个
foreach
循环按顺序拉出东西的能力int
。 int
如果我不关心该项目的排序位置,则无需指定添加(或初始化)项目的能力。- 使用相对简洁的方法执行替换的能力,例如
Aggregate
上面的调用(可能传入IComparer
我没有写到的内容)。
我被困住的是GetEnumerator
实现和我没有记住索引器重载并不困难。
你将如何实现这样的要求。我是在正确的轨道上还是我忽略了一些更优雅的东西?我应该坚持 aDictionary<string,string>
并想出一些方法在开头或结尾插入新项目 - 或者如果我不关心那个项目,就在中间插入?
我只是没有得到什么漂亮、优雅的解决方案?您将如何满足这种需求?