我们常常有一个应用场景,由我们的C#代码,动态生成一个EXE,其应用场景可以非常多,比如软件授权,可以输入授权信息后,生成一个授权的DLL等,那如何实现这个功能呢,就要提到一个技术Emit。

1、Emit概述
Emit,可以称为发出或者产生。在Framework中,与Emit相关的类基本都存在于System.Reflection.Emit命名
空间下。可见Emit是作为反射的一个元素存在的。说道反射,大家应该都不陌生,它允许我们查看程序集的元素据,从而取得形如程序集包含哪些类型,类型包
含哪些方法等等大量的信息。但是反射也仅能够‘看’,而Emit则可以在运行时动态生成代码。接下来就来看看如何用Emit生成代码。

2、程序集(Assembly)和模块(Managed Module)
程序集是一个或多个模块、资源文件的逻辑性分组,其次程序集是重用,安全性和版本控制的最小单元。我们所见到的DLL、EXE都可以称为一个Assembly,一个Assembly里面包含多个Module,不过通常,我们VS编译的时候,会只编译一个Module,假如在一个Assembly中要编译多个Module,则要借助csc.exe实现。

3、动态生成代码操作
定义程序集

//定义一个程序集的名称var asmName = new AssemblyName("MyClass");//首先就需要定义一个程序集var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);

定义模块,和指定程序集的保存名称

//定义一个构建类
var defModuleBuilder = defAssembly.DefineDynamicModule("MyModule", "MyAssembly.dll");

定义一个类 和方法

//定义一个类var defClassBuilder =defModuleBuilder.DefineType("MyClass", TypeAttributes.Public);//定义一个方法
var methodBldr = defClassBuilder.DefineMethod("MyMethod",MethodAttributes.Public,null,//返回类型null//参数的类型);

以上通过创建,已经确定了程序集和模块,也定义了当前模块中的一个类和方法,但这个类的MyMethod方法只定义了一个声明,并没有定义实体操作,以下就需要应用到Emit技术中一个技术OpCode。

OpCode 是描述中间语言 (IL) 指令。这个指令非常多,可以查看微软官网:https://docs.microsoft.com/zh-cn/dotnet/api/system.reflection.emit.opcodes?view=netframework-4.8

通过OpCode我们可以定义方法的内容如下:

//获取IL生成器var il = defMethodBuilder.GetILGenerator();//定义一个字符串il.Emit(OpCodes.Ldstr, "生成的第一个程序");//调用一个函数il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));//返回到方法开始(返回)il.Emit(OpCodes.Ret);
//获取IL生成器var il = defMethodBuilder.GetILGenerator();//定义一个字符串il.Emit(OpCodes.Ldstr, "生成的第一个程序");//调用一个函数il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));//返回到方法开始(返回)il.Emit(OpCodes.Ret);

通过以上的定义,我们完成了一个程序集、模块、类和方法的定义,我们怎么把以上的定义的信息进行创建和c#教程保存,需要调用以下函数:

//创建类型defClassBuilder.CreateType();//保存程序集defAssembly.Save("MyAssemblydll");

我们可以在运行程序看到如下效果:

以下通过创建程序集,并且调用的代码如下:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Text;
using System.Threading.Tasks;namespace ConsoleApp1
{class Program{static void Main(string[] args){CreateAssembly();LoadAssembly();Console.ReadKey();}public static void LoadAssembly(){var ass = AppDomain.CurrentDomain.Load("MyAssembly");var m = ass.GetModule("MyModule");var ts = m.GetTypes();var t = ts.FirstOrDefault();if (t != null){object obj = Activator.CreateInstance(t);var me = t.GetMethod("MyMethod");me.Invoke(obj, null);}}public static void CreateAssembly(){//定义一个程序集的名称var asmName = new AssemblyName("MyAssembly");//首先就需要定义一个程序集var defAssembly = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.RunAndSave);//定义一个构建类var defModuleBuilder = defAssembly.DefineDynamicModule("MyModule", "MyAssembly.dll");//定义一个类var defClassBuilder = defModuleBuilder.DefineType("MyClass", TypeAttributes.Public);//定义一个方法var defMethodBuilder = defClassBuilder.DefineMethod("MyMethod",MethodAttributes.Public,null,//返回类型null//参数类型);//获取IL生成器var il = defMethodBuilder.GetILGenerator();//定义一个字符串il.Emit(OpCodes.Ldstr, "生成的第一个程序");//调用一个函数il.Emit(OpCodes.Call, typeof(Console).GetMethod("WriteLine", new Type[] { typeof(string) }));//返回到方法开始(返回)il.Emit(OpCodes.Ret);//创建类型defClassBuilder.CreateType();//保存程序集defAssembly.Save("MyAssembly.dll");}}
}

显示效果如下:

以上就是详解c# Emit技术的详细内容

详解c# Emit技术相关推荐

  1. 哈工程计算机学院培养方案,哈工程2012年硕士培养方案详解(计算机科学与技术学院).doc...

    哈工程2012年硕士培养方案详解(计算机科学与技术学院) 计算机科学与技术学院 计算机科学与技术 Computer?Science and Technology(0812) 一.适用学科 一级学科名称 ...

  2. 详解SAN存储技术的前世今生

    SAN存储自从80年代产生以来,推动着存储技术不断前进.SAN首先带来了大容量高性能的存储,能够适用于从小型服务器到大型主机的应用需求. SAN存储更重要的核心特点就是存储的大整合, SAN存储可以灵 ...

  3. 万字详解5G车联网技术

    车路协同.车联网.智慧交通.智能网联车.自动驾驶.无人驾驶.高精度地图资料汇总与整理 车路协同优质资料整理地址: 语雀:车路协同.自动驾驶.车联网.智能网联车 · 语雀 (yuque.com) 因阿里 ...

  4. java源码系列:HashMap底层存储原理详解——4、技术本质-原理过程-算法-取模具体解决什么问题

    目录 简介 取模具体解决什么问题? 通过数组特性,推导ascii码计算出来的下标值,创建数组非常占用空间 取模,可保证下标,在HashMap默认创建下标之内 简介 上一篇文章,我们讲到 哈希算法.哈希 ...

  5. 元宇宙技术普及读本重磅问世 详解十大技术 把脉数字经济 前瞻产业布局

    转自 元宇宙共识圈 王恩东.倪光南.沈昌祥.郑纬民--四位中国工程院院士联袂力荐 倪健中.姚前.李正茂.朱嘉明.肖风.敖然等权威专家一致推荐 汇聚元宇宙技术专家及产业一线佼佼者倾力撰写 元宇宙技术普及 ...

  6. java技术详解_Java反射技术详解及实例解析

    前言 相信很多人都知道反射可以说是Java中最强大的技术了,它可以做的事情太多太多,很多优秀的开源框架都是通过反射完成的,比如最初的很多注解框架,后来因为java反射影响性能,所以被运行时注解APT替 ...

  7. 一篇文章详解大数据技术和应用场景

    " 本文作者 陈睿 ,优知学院创始人 新技术.新趋势往往趋之若鹜却又很难说的透彻,希望这篇文章能让大家完整的理解什么是大数据:该篇包含:大数据.技术.场景应用以及大数据的岗位. 什么是大数据 ...

  8. 框架详解_Qt开发技术:QtCharts(一)QtCharts基本介绍以及图表框架详解

    若该文为原创文章,未经允许不得转载 原博主博客地址:https://blog.csdn.net/qq21497936 原博主博客导航:https://blog.csdn.net/qq21497936/ ...

  9. 详解Po.et 技术栈

    点击上方 "蓝色字" 可关注我们! 编辑:铅笔盒 Po.et 核心组件概述 本文由Po.et核心开发成员Lautaro Dragan 撰写,详细剖析了Po.et的技术细节. 在Po ...

最新文章

  1. Scrum团队选择scrum看板工具的7点特征
  2. 如何检查你的项目是不是真的需要用到 AI?
  3. Avahi DOS攻击broadcast-avahi-dos
  4. diy手工制作泡沫小球_废物利用手工DIY教程。一次性筷子变废为宝,手工制作木屋模型...
  5. 如何学好初中计算机,初中生怎么学习方法好 十大方法告诉你
  6. leetcode题解72-编辑距离
  7. mysql缓存怎么防止缓存击穿_带你搞明白什么是缓存穿透、缓存击穿、缓存雪崩...
  8. 漫画:为什么一到年底,部分网站就会出现日期混乱?
  9. 通过Cookie存取用户游览记录的代码示例
  10. ELK——Logstash 2.2 mutate 插件【翻译+实践】
  11. 微信小程序:使用阿里icon图标
  12. 计算机c语言试题文档,计算机二级C语言考试试题
  13. 微信小程序从云存储中读取图片
  14. 序列化和反序列化(示例)
  15. python-opencv尺寸测量
  16. 客户细分_客户细分初学者指南
  17. panda3d python教程_图解 Panda3D引擎开发入门
  18. 如何用服务器内存做系统盘,服务器内存扩容怎么做
  19. 初探机器学习与评分卡模型
  20. 计算机技术属于全日制工程硕士吗,计算机技术全日制硕士培养方案

热门文章

  1. linux服务器开放指定端口号相关命令
  2. CURL GITLAB API
  3. PageOffice在线只读打开word文件并禁止复制
  4. 网络安全前景怎么样?怎么自学?看这一篇就够了
  5. 网络营销和整合营销具体是什么?
  6. 2.3 Git 基础 - 查看提交历史
  7. 账号安全总结-业务安全测试实操(27)
  8. C语言学习笔记-宏定义-SWAP交换两个变量值
  9. 外企面试的常见英语表达6
  10. C语言常用字符串函数详解