.NET 5运行时编译字符串触发PlatformNotSupportedException求替代方案
问题原因
你遇到的System.PlatformNotSupportedException报错是因为.NET 5及更高版本移除了传统CSharpCodeProvider提供的运行时从字符串编译代码的能力,原有基于CodeDOM的实现方案不再兼容新版本框架。
替代实现方案
使用微软官方提供的Roslyn编译器库实现同等功能,步骤如下:
- 先为项目安装NuGet依赖包:
Microsoft.CodeAnalysis.CSharp - 将原有代码替换为下方实现:
using Microsoft.CodeAnalysis; using Microsoft.CodeAnalysis.CSharp; using System.Reflection; using System.Runtime.Loader; private void Button_Click(object sender, RoutedEventArgs e) { string sourceCode = @" public class SomeClass { public int Add42 (int parameter) { return parameter + 42; } }"; // 构建语法树 SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(sourceCode); // 配置编译参数 string assemblyName = Path.GetRandomFileName(); // 添加基础程序集引用,根据代码需要可扩展其他引用 var references = new List<MetadataReference> { MetadataReference.CreateFromFile(typeof(object).Assembly.Location), MetadataReference.CreateFromFile(Assembly.GetExecutingAssembly().Location) }; CSharpCompilation compilation = CSharpCompilation.Create( assemblyName, syntaxTrees: new[] { syntaxTree }, references: references, options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); // 编译到内存流 using var ms = new MemoryStream(); var emitResult = compilation.Emit(ms); if (!emitResult.Success) { // 编译失败时可遍历emitResult.Diagnostics查看错误信息 textBox.Text = "编译失败"; return; } ms.Seek(0, SeekOrigin.Begin); // 加载编译生成的程序集 Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms); // 实例化类并调用方法,逻辑和原代码完全一致 object typeInstance = assembly.CreateInstance("SomeClass"); MethodInfo mi = typeInstance.GetType().GetMethod("Add42"); int methodOutput = (int)mi.Invoke(typeInstance, new object[] { 1 }); textBox.Text = methodOutput.ToString(); }
注意事项
- 如果需要编译的代码依赖其他类库,只需在
references列表中添加对应类库dll的路径即可 - 运行时编译并执行外部代码存在安全风险,需确保所编译的源代码来源可信,避免执行恶意代码
内容的提问来源于stack exchange,提问作者Sheikh_hasan
相关产品推荐
相关产品推荐

