NET 编译器平台(.NET Compiler Platform)
也称为Roslyn,是Microsoft的一组用于C#和Visual Basic (VB.NET) 语言的开源 编译器和代码分析 API。
该项目特别包括C# 和 VB.NET 编译器的自托管版本——用语言本身编写的编译器。编译器可通过传统的命令行程序使用,也可作为 API 在 .NET 代码中本地使用。Roslyn 公开了用于代码句法(词法)分析、语义分析、CIL动态编译和代码发射的模块。
例子
下面是一个简单的例子,来简单的使用。
创建一个C#控制台程序,引用下面的包。
<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Scripting" Version="4.6.0" />
</ItemGroup>
这里放入了两个脚本代码,展示如何运行。
直接上代码
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Scripting;
using Microsoft.CodeAnalysis.Scripting;
using System.Diagnostics;
using Microsoft.CodeAnalysis.Emit;
using System.Reflection;
namespace RoslynCosonle
{
class Program
{
static string code0 = @"
using System;
namespace RoslynCompileSample
{
public class Fun
{
public static string GetName()
{
return ""Get Fun.Name"";
}
}
}";
static string code1 = @"
using System;
namespace RoslynCompileSample
{
public class Writer
{
public void Write(string message)
{
Console.WriteLine(message);
Console.WriteLine(Fun.GetName());
}
}
}";
static void Main(string[] args)
{
// 随机程序集名称
string assemblyName = Path.GetRandomFileName();
Console.WriteLine("assemblyName:" + assemblyName);
//Debug.WriteLine("assemblyName : "+assemblyName);
// 元数据引用
var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
Console.WriteLine("assemblyPath:" + assemblyPath);
MetadataReference[] references = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Enumerable).Assembly.Location),
MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Private.CoreLib.dll")),
MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Console.dll")),
MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll"))
};
SyntaxTree[] syntaxTree =
{
CSharpSyntaxTree.ParseText(code1),
CSharpSyntaxTree.ParseText(code0)
};
// 创建编译对象
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
syntaxTrees: syntaxTree,
references: references,
options: new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var ms = new MemoryStream())
{
// 将编译后的IL代码放入内存中
EmitResult result = compilation.Emit(ms);
// 编译失败,提示
if (!result.Success)
{
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
{
Console.Error.WriteLine("{0}: {1}", diagnostic.Id, diagnostic.GetMessage());
}
}
else
{
// 编译成功则从内存中加载程序集
ms.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(ms.ToArray());
// 反射获取程序集中 的类
Type type = assembly.GetType("RoslynCompileSample.Writer");
// 创建该类的实例
object obj = Activator.CreateInstance(type);
// 通过反射方式调用类中的方法。(Hello World 便是我们传入方法的参数)
type.InvokeMember("Write",
BindingFlags.Default | BindingFlags.InvokeMethod,
null,
obj,
new object[] { "Hello World" });
}
}
}
}
}
执行结果
其他资料
引用和参考1
引用和参考2
引用和参考3
引用和参考4