C#延迟模板字符串插值问询:预定义模板占位符填充实现
解决C#预定义模板字典的动态填充问题
哎,这个坑我太熟了!你想用C#的字符串插值语法预定义模板字典,但直接写$"{Value1}"这种方式根本没法实现动态填充——因为C#的$""字符串插值是编译时处理的:定义templates字典的时候,编译器会立刻尝试解析{Value1}和{Value2},如果当前作用域没有这些变量直接报错;就算有,生成的字符串也是固定死的,后续没法再替换占位符。
那该怎么实现“预定义模板,每次调用方法时动态填充”的需求呢?给你两种实用的方案:
方案1:正则匹配占位符+字典替换
这是最直接的实现方式,把模板写成带{占位符}的普通字符串,然后用正则找出所有占位符,从传入的参数字典里替换对应的值。
代码实现
首先定义你的静态模板字典(注意不要用$"",就写普通字符串):
private static readonly Dictionary<string, string> _templates = new Dictionary<string, string> { { "Key1", "{Value1}" }, { "Key2", "Constant with {Value2}" } };
然后实现FillTemplates方法:
public IDictionary<string, string> FillTemplates(IDictionary<string, object> values) { var filledTemplates = new Dictionary<string, string>(); // 预编译正则,匹配{xxx}格式的占位符 var placeholderPattern = new Regex(@"\{(\w+)\}", RegexOptions.Compiled); foreach (var (templateKey, templateValue) in _templates) { // 替换所有占位符 var filledValue = placeholderPattern.Replace(templateValue, match => { var placeholderName = match.Groups[1].Value; // 如果传入的值里有对应key,就替换;没有就保留原占位符(也可以改成空字符串) return values.TryGetValue(placeholderName, out var value) ? value.ToString() : match.Value; }); filledTemplates.Add(templateKey, filledValue); } return filledTemplates; }
使用示例
调用的时候直接传包含占位符对应值的字典就行:
var result = FillTemplates(new Dictionary<string, object> { { "Value1", "Hello from Template 1" }, { "Value2", "Dynamic World" } }); // 结果: // result["Key1"] = "Hello from Template 1" // result["Key2"] = "Constant with Dynamic World"
方案2:用匿名类型+反射替换(更贴近“插值”写法)
如果你更喜欢传匿名类型而不是字典,也可以用反射来匹配占位符和属性名,写法更简洁:
代码实现
模板字典和方案1一样,然后实现方法:
public IDictionary<string, string> FillTemplates(dynamic values) { var filledTemplates = new Dictionary<string, string>(); var valueType = values.GetType(); foreach (var (templateKey, templateValue) in _templates) { var filledValue = templateValue; // 提取所有唯一的占位符 var placeholders = Regex.Matches(templateValue, @"\{(\w+)\}") .Cast<Match>() .Select(m => m.Groups[1].Value) .Distinct(); foreach (var placeholder in placeholders) { // 反射获取匿名类型的属性值 var property = valueType.GetProperty(placeholder); if (property != null) { var value = property.GetValue(values); filledValue = filledValue.Replace($"{{{placeholder}}}", value?.ToString() ?? string.Empty); } } filledTemplates.Add(templateKey, filledValue); } return filledTemplates; }
使用示例
调用时传匿名类型,写法更直观:
var result = FillTemplates(new { Value1 = "Hi there", Value2 = "Anonymous Type Magic" });
关键提醒
一定要记住:不要用$""定义模板!$""是编译时插值,会直接把当前作用域的变量值塞进字符串,生成的是固定内容,完全没法后续动态替换。必须把模板写成带占位符的普通字符串,留到运行时再处理。
内容的提问来源于stack exchange,提问作者Sergey Ionov
相关产品推荐
相关产品推荐

