.net core 怎样动态编译实现类似脚本的功能
你可以使用 CodeDom ( CodeDomProvider ) 或 roslyn( 完整代码 / 片段 )来实现。CodeDom的优势:
直接内置,不用引用庞大的Nuget包;编译速度快,配置简单;支持Javascript;CodeDom的劣势:
只支持低版本的框架和语言;不支持分析功能;roslyn的优势:
强大的分析功能;灵活的实现方式;详细的配置选项;支持高级语法特性;roslyn的劣势:
需要引入巨大的包(Microsoft.CodeAnalysis.CSharp,还有个小不点);编译速度缓慢;下面的代码演示了实现的三个思路:using System;using System.CodeDom.Compiler;using System.Collections.Generic;using System.IO;using System.Linq;using System.Reflection;using Microsoft.CodeAnalysis;using Microsoft.CodeAnalysis.CSharp;using Microsoft.CodeAnalysis.CSharp.Scripting;using Microsoft.CodeAnalysis.Scripting;namespace CompileSample{ class Program { static void Main(string args) { var source = @" using System; namespace Sample { public class Program { public static void Main() { Console.WriteLine(""hello, world""); } } }"; var a = GetAssemblyFromSourceByCodeDom(source); var b = GetAssemblyFromSourceByRoslyn(source); var methodA = a.CreateInstance("Sample.Program").GetType().GetMethod("Main"); var methodB = b.CreateInstance("Sample.Program").GetType().GetMethod("Main"); methodA.Invoke(null, null); methodB.Invoke(null, null); RunStringCodeByRoslyn(@"Console.WriteLine(""hello, world"");"); Console.ReadKey(); } static Assembly GetAssemblyFromSourceByCodeDom(params string source) { using var provider = CodeDomProvider.CreateProvider( "CSharp", new Dictionary\u0026lt;string, string\u0026gt; { { "CompilerVersion", "v4.0" }}); var compileResult = provider.CompileAssemblyFromSource( new CompilerParameters() { IncludeDebugInformation = false, TreatWarningsAsErrors = true, WarningLevel = 4, GenerateExecutable = false, GenerateInMemory = true }, source); if (compileResult.Errors.Count \u0026gt; 0) { throw new ArgumentException(); } return compileResult.CompiledAssembly; } static Assembly GetAssemblyFromSourceByRoslyn(string source) { var compilation = CSharpCompilation.Create( null, new { CSharpSyntaxTree.ParseText(source) }, new { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }, new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)); using var memSteam = new MemoryStream(); var emitResult = compilation.Emit(memSteam); if (!emitResult.Success || emitResult.Diagnostics.FirstOrDefault(x =\u0026gt; x.Severity \u0026gt; 0) != null) { throw new ArgumentException(); } memSteam.Seek(0, SeekOrigin.Begin); return Assembly.Load(memSteam.ToArray()); } static void RunStringCodeByRoslyn(string source) { _ = CSharpScript.RunAsync(source, ScriptOptions.Default .AddReferences(new { MetadataReference.CreateFromFile(typeof(object).Assembly.Location) }) .AddImports("System") .WithLanguageVersion(LanguageVersion.CSharp8) .WithOptimizationLevel(OptimizationLevel.Release) .WithEmitDebugInformation(false) .WithWarningLevel(4) ).Result; } }}
推荐阅读
- 聪明人养花,这3种“花”怎样也要养一盆,每年能省不少医药费
- 互联网怎样解决“家政服务上门速度慢”的问题
- 怎样看待从1月8号起,QQ钱包开始提现收费
- 银行it人怎样转型
- 汽车|冬天怎样让车内温度快速升高?座椅加热的最佳使用方式二,外循环的作用总结
- 怎样进入通信行业
- 怎样评价扶他柠檬茶的小说《云养汉》的结尾
- 怎样成为一名合格的Python程序员?
- 怎样评价华为、诺基亚、中兴中标中国移动高端路由交换设备扩容集采
- 怎样评价类似前橙会、百老汇、南极圈这样类型的离职帮抱团,对企业的积极意义和消极意义
