using?Microsoft.CodeAnalysis;
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Reflection;
using System.Runtime;
using System.Text;
using System.Globalization;
using Microsoft.CodeAnalysis.CSharp;
using Newtonsoft.Json;
using Smart.Text.Japanese;namespace NLuaAndRoslynCompare5
{public class RoslynClass{public static object Transform(string csharp,params object[] pares){ var sourceCodeText = $@"
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Linq;
using Smart.Text.Japanese;
using System.Globalization;namespace RoslynDynamicGenerate
{{public class DynamicGenerateClass{{public object Generate(object par){{ {csharp}}} }}
}}
";var syntaxTree = CSharpSyntaxTree.ParseText(sourceCodeText, new CSharpParseOptions(LanguageVersion.Latest)); // 獲取代碼分析得到的語(yǔ)法樹(shù)var assemblyName = $"RoslynDynamicGenerate";// 創(chuàng)建編譯任務(wù)var metadata = GetMetadataReference(typeof(System.Text.RegularExpressions.Regex),typeof(StringExpand), typeof(KanaConverter), typeof(List<>), typeof(IDictionary), typeof(JapaneseCalendar),typeof(CultureInfo),typeof(DateTime),typeof(JsonConvert), typeof(object), typeof(AssemblyTargetedPatchBandAttribute));var compilation = CSharpCompilation.Create(assemblyName) //指定程序集名稱.WithOptions(new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary))//輸出為 dll 程序集 .AddReferences(metadata) //添加程序集引用 .AddSyntaxTrees(syntaxTree) // 添加上面代碼分析得到的語(yǔ)法樹(shù) ;using (var memory = new MemoryStream()){var compilationResult = compilation.Emit(memory);if (compilationResult.Success){try{var assembly = Assembly.Load(memory.ToArray());var type = assembly.GetType("RoslynDynamicGenerate.DynamicGenerateClass");var obj = Activator.CreateInstance(type);var methodInfo = type.GetMethod("Generate");return methodInfo.Invoke(obj, pares)?.ToString();}finally{memory.Close();}}else{foreach (var diagnositic in compilationResult.Diagnostics){Console.WriteLine(diagnositic);}throw new ApplicationException($"下面C#語(yǔ)句有語(yǔ)法錯(cuò)誤{sourceCodeText}");}}}/// <summary>/// 從類型獲取原數(shù)據(jù)引用/// </summary>/// <param name="types">類型集合</param>/// <returns></returns>static List<MetadataReference> GetMetadataReference(params Type[] types){var list = new List<MetadataReference>();foreach (var type in types){var metadateRef = MetadataReference.CreateFromFile(type.Assembly.Location);list.Add(metadateRef);foreach (var assembly in type.Assembly.GetReferencedAssemblies()){ list.Add(MetadataReference.CreateFromFile(Assembly.Load(assembly).Location)); }}return list;}}
}
調(diào)用方法如下:
List<string> Roslyn(){var list = new List<string>();var csharp = @"return DateTime.Now.ToString(""yyyy-MM-dd HH:mm:ss.ffffff""); ";for (int i = 0; i < 1000; i++){list.Add(RoslynClass.Transform(csharp, 1).ToString());} return list;}