C#中带有可变内容的字符串插值

时间:2017-04-08 00:23:00

标签: c#

可以将字符串的模板存储在变量中并使用插值吗?

var name = "Joe";
var template = "Hi {name}";

然后我想做类似的事情:

var result = $template;

原因是我的模板将来自数据库。

4 个答案:

答案 0 :(得分:6)

我猜这些字符串将始终具有相同数量的参数,即使它们可以更改。例如,今天template"Hi {name}",明天可能为"Hello {name}"

简短回答:不,你不能做你提出的建议。

备选方案1:使用string.Format方法。

您可以在数据库中存储以下内容:

"Hi {0}"

然后,当您从db中检索字符串模板时,您可以编写:

var template = "Hi {0}"; //retrieved from db
var name = "Joe";
var result = string.Format(template, name);
//now result is "Hi Joe"

有2个参数:

var name2a = "Mike";
var name2b = "John";
var template2 = "Hi {0} and {1}!"; //retrieved from db
var result2 = string.Format(template2, name2a, name2b);
//now result2 is "Hi Mike and John!"

备选方案2:使用占位符。

您可以在数据库中存储以下内容:

"Hi {name}"

然后,当您从db中检索字符串模板时,您可以编写:

var template = "Hi {name}"; //retrieved from db
var name = "Joe";
var result = template.Replace("{name}", name);
//now result is "Hi Joe"

有3个参数:

var name2a = "Mike";
var name2b = "John";
var template2 = "Hi {name2a} and {name2b}!"; //retrieved from db
var result2 = template2
    .Replace("{name2a}", name2a)
    .Replace("{name2b}", name2b);
//now result2 is "Hi Mike and John!"

注意您为占位符选择的令牌。在这里,我使用了大括号{}。您应该找到一些不太可能导致与其他文本冲突的内容。这完全取决于你的背景。

答案 1 :(得分:5)

这可以根据需要使用动态编译来完成,例如通过Microsoft.CodeAnalysis.CSharp.Scripting包。例如:

var name = "Joe";
var template = "Hi {name}";
var result = await CSharpScript.EvaluateAsync<string>(
    "var name = \"" + name + "\"; " +
    "return $\"" + template + "\";");

请注意,这种方法很慢,您需要添加更多逻辑来处理字符串中引号(和注入攻击)的转义,但是以上内容只是概念证明。

答案 2 :(得分:1)

不,你不能这样做,因为它在创建字符串时需要name值(编译时)。请考虑改为使用String.FormatString.Replace

答案 3 :(得分:1)

我的应用也有同样的需求,因此将使用 String.Replace() 分享我的解决方案。如果您能够使用 LINQ,那么您可以使用 Aggregate 方法(如果您熟悉函数式编程,它是一个减少函数)与提供您想要的替换的字典相结合。

string template = "Hi, {name} {surname}";

Dictionary<string, string> substitutions = new Dictionary<string, string>() {
    { "name", "Joe" },
    { "surname", "Bloggs" },
};

string result = substitutions.Aggregate(template, (args, pair) =>
    args.Replace($"{{{pair.Key}}}", pair.Value)
);
// result == "Hi, Joe Bloggs"

这是从 template 开始,然后迭代替换字典中的每个项目,替换每个项目的出现。一次 Replace() 调用的结果被送入下一次的输入中,直到所有替换都执行完毕。

{{{pair.Key}}} 位只是为了转义用于查找占位符的 {}