Roslyn 动态编译

news2024/10/3 8:16:43

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/787712.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue2路由(个人学习笔记四)

目录 友情提醒第一章、路由简介1.1&#xff09;什么是路由1.2&#xff09;安装路由插件 第二章、自定义路由器2.1&#xff09;创建路由器文件index.js文件2.2&#xff09;index.js文件中配置路由信息 第三章、使用路由器3.1&#xff09;在main.js文件中将路由器绑定到Vue对象3.…

查看maven发布时间的方法

查看maven发布时间的方法如下【 打开maven官网 选中Release Notes 即可查看对应版本的发布时间 】

【Linux命令200例】cmp文件比较工具

&#x1f3c6;作者简介&#xff0c;黑夜开发者&#xff0c;全栈领域新星创作者✌&#xff0c;2023年6月csdn上海赛道top4。 &#x1f3c6;本文已收录于专栏&#xff1a;Linux命令大全。 &#x1f3c6;本专栏我们会通过具体的系统的命令讲解加上鲜活的实操案例对各个命令进行深入…

微信小程序开发知识点总结(不断补充)

一、怎样实现小程序与数据库的交互原理 微信小程序开发里面是不能直接写数据库连接文件&#xff0c;如果要实现与数据库的交互&#xff0c;就需要用到中间的接口。&#xff08;这个接口可以理解成springboot项目中controller层的RequestMapping的URL&#xff09;具体用法如下&…

Thunderbird 115 带来了Supernova UI 和先进功能

导读Thunderbird 115 带来了Supernova UI 和先进功能&#xff0c;将电子邮件带入了新的高度。 流行的开源电子邮件客户端 Mozilla Thunderbird 推出了最新版本Thunderbird 115&#xff0c;它带来了一系列令人兴奋的功能和改进。更新带来了令人耳目一新的超新星用户界面(UI)&…

STM32MP157驱动开发——按键驱动(线程化处理)

文章目录 “线程化处理”机制&#xff1a;内核函数线程化处理方式的按键驱动程序(stm32mp157)编程思路button_test.cgpio_key_drv.cMakefile修改设备树文件编译测试 “线程化处理”机制&#xff1a; 工作队列是在内核的线程的上下文中执行的 工作队列中有多个 work&#xff0…

matlab安装激活后报错找不到icuuc54.dll

matlab激活后&#xff0c;有报错找不到icuuc54.dll 解决办法&#xff1a; 这是因为破解用的版本不一样&#xff0c;我下载的是matlab2016b&#xff0c;但是破解时&#xff0c;在网上下载的matlab2016a的破解包&#xff0c;所以我重新下载2016b的crack包后&#xff0c;然后再在…

使用Vs Studio和Cmake生成C++库

使用Vs Studio和Cmake生成C库 在windows系统下&#xff0c;由于没有C的编译器&#xff0c;想通过源码安装、加载C的库存在不方便的地方。本文将介绍通过使用Vs Studio运用Cmake的方式&#xff0c;编译一个简单的自定义库&#xff0c;并进行加载、调用。 工程源代码 前提条件 …

Python增删改查小练习

目录 1. List操作-增加 2. List操作-查询 3. List操作-修改 4. List操作-删除 资料获取方法 1. List操作-增加 List Append(“xx”) 插入到列表尾部 Insert(x,xx) 在指定的位置插入 Extend 将列表的元素分开,插入到之前列表的尾部 小练习: 把一个字符串”abcdefg…

小白必看系列之c语言中常见操作符示例和用法总结

文章目录 前言算术操作符&#xff08;Arithmetic Operators&#xff09;代码示例代码解析 关系操作符&#xff08;Relational Operators&#xff09;代码示例代码解析 逻辑操作符&#xff08;Logical Operators&#xff09;代码示例代码解析 位操作符&#xff08;Bitwise Opera…

矩阵svd分解和矩阵的伪逆

真该好好学习一下Latex数学公式的语法和规则了&#xff0c;否则&#xff0c;连写个博客都没法写&#xff0c;这叫什么事&#xff01; https://blog.csdn.net/ViatorSun/article/details/82826664 直接上数学博士写的ppt图&#xff08;肯定比我在这里胡说八道强的多&#xff0…

【设计模式——学习笔记】23种设计模式——原型模式Prototype(原理讲解+应用场景介绍+案例介绍+Java代码实现)

原型模式 介绍 原型模式指用通过拷贝原型实例创建新的实例&#xff0c;新实例和原型实例的属性完全一致原型模式是一种创建型设计模式工作原理是通过调用原型实例的 clone()方法来完成克隆&#xff0c;原型实例需要实现Cloneable接口&#xff0c;并重写clone()方法需要为每个…

平台化的测试工具推荐|一站式测试平台RunnerGo

互联网行业的发展到今天越来越多的公司更加注重工作效率和团队协作&#xff0c;越来越多的产品也趋于平台化&#xff0c;平台化也更有利于提高团队效率&#xff0c;代码管理、持续构建、持续部署这些工具的发展都是非常超前的&#xff0c;它们对于团队协作的支持和工作效率的提…

河南移动联合中兴打造SPNPTN网络融合示范样板

最近河南移动和中兴在濮阳进行SPN和PTN两网融合规模部署&#xff0c;可以充分展示出PTN网络价值&#xff0c;并优化网络结构、降低网络运营成本&#xff0c;实现SPN和PTN网络的融合融通&#xff0c;在增强SPN网络综合业务承载能力之余也能提升了网络性能。 河南移动现在是SDH、…

CF1837 A-D

A题 题目链接&#xff1a;https://codeforces.com/problemset/problem/1837/A 基本思路&#xff1a; 要求计算蚂蚱到达位置 x最少需要多少次跳跃&#xff0c;并输出蚂蚱的跳跃方案。因为每次可以向左或向右跳跃一定距离&#xff08;距离必须为整数&#xff09;&#xff0c;但是…

微服务探索之路06篇k8s配置文件Yaml部署Redis使用Helm部署MongoDB和kafka

1 安装Redis 1.1创建配置文件redis.conf 切换到自己的目录下如本文是放在/home/ubuntu下 cd /home/ubuntuvim redis.conf bind 0.0.0.0 protected-mode yes port 6379 requirepass qwe123456 tcp-backlog 511 timeout 0 tcp-keepalive 300 daemonize no pidfile /var/run/r…

STM32MP157驱动开发——按键驱动(工作队列)

文章目录 “工作队列”机制&#xff1a;内核函数work_struct 结构体定义 work使用 work &#xff1a;schedule_workworkqueue 其他函数 工作队列方式的按键驱动程序(stm32mp157)编程思路button_test.cgpio_key_drv.cMakefile修改设备树文件编译测试 “工作队列”机制&#xff1…

UDS之11服务

11服务&#xff1a; 功能&#xff1a;控制MCU进行重启&#xff0c;重启分为硬重启和软重启&#xff0c;11服务一般代表软重启&#xff0c;虽然它里面有个子服务是硬件重启&#xff0c;这里需要注意下&#xff1b;硬重启在日常工作中一般代表B重启。命令格式&#xff08;请求&am…

外贸找客户工具之邮件群发:MaxBulk Bulk Mailer Pro 9.5

MaxBulk Bulk Mailer Pro 是一款快速的批量邮件软件&#xff0c;旨在帮助在一次操作中向大量电子邮件 ID 发送批量电子邮件。直接将电子邮件发送到收件箱而不是垃圾邮件。该工具的目的是使批量电子邮件处理过程快速而精确&#xff0c;并且它配备了很多高级功能来实现此目的。用…

集成学习——Boosting算法:Adaboost、GBDT、XGBOOST和lightGBM的简要原理和区别

1、Boosting算法 Boosting算法是通过串联的方式&#xff0c;将一组弱学习器提升为强学习器算法。它的工作机制如下&#xff1a; &#xff08;1&#xff09;用初始训练集训练出一个基学习器&#xff1b; &#xff08;2&#xff09;依据基学习器的表现对训练样本分布进行调整&…