我有一个key value pair
字典,我需要使用字符串插值,然后根据命名参数映射字符串。请帮我。
// code removed for brevity
var rawmessage = "Hello my name is {Name}"; // raw message
var dict= new Dictionary<string, object>();
dict.Add("{Name}", response.Name);
我希望能够做到这样的事情:
// Pseudo code
$"Hello my name is {Key}", dict;
解决方案我发现到现在为止:
var message = parameters.Aggregate(message,
(current, parameter) => current.Replace(parameter.Key, parameter.Value.ToString()));
它工作正常,但我的经理真的希望我使用String Interpolation with Dictionary。我不知道如何实现这一目标。请指导我。
它工作正常,但我的经理真的希望我使用String Interpolation with Dictionary。我不知道如何实现这一目标。
你不能这样做。 C#interpolated string不是模板引擎,而是编译时功能,转换为String.Format
调用。这就是为什么你不能在常量表达式中使用字符串插值的原因。
我想使用String Interpolation将命名参数(在字典中作为Keys存在)映射到它们各自的值。但我不想使用String.Replace。有什么出路吗?
实际上你可以使用几种模板引擎(主要用于记录),所以你不需要重新发明轮子。例如,您可能会发现Serilog很有趣。
另见这个帖子:What's a good way of doing string templating in .NET?
问题是C#中的string interpolation只是string.Format
的语法糖包装。字符串被编译为相同的代码。以此代码为例:
public string GetGreeting1(string name)
{
return string.Format("Hello {0}!", name);
}
public string GetGreeting2(string name)
{
return $"Hello {name}!";
}
两种方法的IL输出完全相同:
GetGreeting1:
IL_0000: ldstr "Hello {0}!"
IL_0005: ldarg.1
IL_0006: call System.String.Format
IL_000B: ret
GetGreeting2:
IL_0000: ldstr "Hello {0}!"
IL_0005: ldarg.1
IL_0006: call System.String.Format
IL_000B: ret
所以你拥有的解决方案是完全有效的,而且我以前使用过的解决方案。唯一可能的改进是,如果您打算进行大量替换,如果您切换到使用StringBuilder
,您可能会发现性能优势。您可能会在Nuget上找到一个可以为您完成的库,但这可能只是为了您的目的而过度杀伤。
另外,我为此做了一个扩展类。有了额外的奖励,我还添加了一个使用具有任意数量参数的对象的方法,该参数使用反射来进行替换:
public static class StringReplacementExtensions
{
public static string Replace(this string source, Dictionary<string, string> values)
{
return values.Aggregate(
source,
(current, parameter) => current
.Replace($"{{{parameter.Key}}}", parameter.Value));
}
public static string Replace(this string source, object values)
{
var properties = values.GetType().GetProperties();
foreach (var property in properties)
{
source = source.Replace(
$"{{{property.Name}}}",
property.GetValue(values).ToString());
}
return source;
}
}
并使用这样的:
var source = "Hello {name}!";
//Using Dictionary:
var dict = new Dictionary<string, string> { { "name", "David" } };
var greeting1 = source.Replace(dict);
Console.WriteLine(greeting1);
//Using an anonymous object:
var greeting2 = source.Replace(new { name = "David" });
Console.WriteLine(greeting2);