如何实现基于用户输入的动态字符串插值功能?
动态用户输入字符串插值实现方案
你当前的写法无法达到预期效果,C#的$""字符串插值是编译期特性,仅能解析代码编写阶段就确定的占位符,无法处理运行时用户传入的动态模板内容,可通过以下两种方案实现需求:
方案1:字典+正则替换(最推荐,安全无风险)
该方案完全可控,无代码注入风险,性能更高,适合绝大多数场景:
using System.Text.RegularExpressions; public string Foo(string input) { // 存储所有允许用户使用的变量 var allowedVariables = new Dictionary<string, string> { {"user", "random_user_name"}, {"address", "random_address"}, {"city", "random_city"} }; // 匹配所有{变量名}格式的占位符进行替换 return Regex.Replace(input, @"\{(\w+)\}", match => { var variableName = match.Groups[1].Value; return allowedVariables.TryGetValue(variableName, out var value) ? value : match.Value; }); }
如果用户输入了不存在的变量名,以上代码会直接返回原占位符内容,你也可以根据需求改成返回空值或者提示文本。
方案2:Roslyn动态编译(仅适用于完全信任用户输入的场景)
如果需要支持更复杂的插值逻辑(比如简单运算、属性调用等),可以用Roslyn脚本引擎动态执行插值逻辑,但该方案存在代码注入风险,仅可在用户输入100%可信的场景下使用:
using Microsoft.CodeAnalysis.CSharp.Scripting; using Microsoft.CodeAnalysis.Scripting; public async Task<string> Foo(string input) { string user = "random_user_name"; string address = "random_address"; string city = "random_city"; // 构造插值代码,转义模板内的双引号避免语法错误 var interpolatedCode = "$\"" + input.Replace("\"", "\\\"") + "\""; var scriptOptions = ScriptOptions.Default.AddReferences(typeof(string).Assembly); // 将局部变量传入脚本上下文执行 return await CSharpScript.EvaluateAsync<string>(interpolatedCode, scriptOptions, new { user, address, city }); }
使用该方案需要先安装Microsoft.CodeAnalysis.CSharp.Scripting NuGet包。
内容的提问来源于stack exchange,提问作者JD_1609
相关产品推荐
相关产品推荐

