using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.Loader;
namespace ConsoleApp10
{
public class Program
{
public static void Main(string[] args)
{
string json = @"[{id:1,name:'学生1',address:'苏州'}
,{id:2,name:'学生2',address:'苏州'}
,{id:3,name:'学生3',address:'嘉兴'}]";
JArray jarray = JArray.Parse(json);
Console.WriteLine("原始数据:");
Console.WriteLine(jarray);
//代码
string codeToCompile = @"
using Newtonsoft.Json.Linq;
namespace RoslynCompileSample
{
public class RoslynCompileClass
{
public JArray RoslynCompileAction(JArray jarray)
{
foreach (JObject r in jarray)
{
if (r.ContainsKey(""name"") && r[""name""].ToString() == ""学生1"")
{
r[""address""] = ""嘉兴"";
}
r[""country""] = ""中国"";
}
return jarray;
}
}
}";
try
{
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(codeToCompile);
//添加引用
string assemblyName = Path.GetRandomFileName();
var refPaths = new[]
{
typeof(System.Object).GetTypeInfo().Assembly.Location,
typeof(Console).GetTypeInfo().Assembly.Location,
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "System.Runtime.dll"),
Path.Combine(Path.GetDirectoryName(typeof(System.Runtime.GCSettings).GetTypeInfo().Assembly.Location), "netstandard.dll"),
Path.Combine(Environment.CurrentDirectory, "Newtonsoft.Json.dll")
};
MetadataReference[] references = refPaths.Select(r => MetadataReference.CreateFromFile(r)).ToArray();
//编译
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: new[] { syntaxTree },
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
EmitResult result = compilation.Emit(ms);
if (!result.Success)
{
//编译失败
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
}
else
{
//编译成功
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = AssemblyLoadContext.Default.LoadFromStream(ms);
var type = assembly.GetType("RoslynCompileSample.RoslynCompileClass");
var instance = assembly.CreateInstance("RoslynCompileSample.RoslynCompileClass");
var meth = type.GetMember("RoslynCompileAction").First() as MethodInfo;
var returnResult = meth.Invoke(instance, new[] { jarray });
Console.WriteLine("结果数据:");
Console.WriteLine(returnResult);
}
}
}
catch (Exception ex)
{
}
}
}
}
C# 将字符串转化成方法执行(动态方法)
于 2023-06-09 17:05:24 首次发布