如何将一段文本编译成C#内存程序的过程
string code = null; // 1. 生成要编译的代码。(示例为了简单直接从程序集内的资源中读取)
Stream stram = typeof(CodeDOM).Assembly
.GetManifestResourceStream("TestOptimizeReflection.用户手册.txt");
using( StreamReader sr = new StreamReader(stram) ) {
code = sr.ReadToEnd();
} //Console.WriteLine(code); // 2. 设置编译参数,主要是指定将要引用哪些程序集
CompilerParameters cp = new CompilerParameters();
cp.GenerateExecutable = false;
cp.GenerateInMemory = true;
cp.ReferencedAssemblies.Add("System.dll");
cp.ReferencedAssemblies.Add("OptimizeReflection.dll"); // 3. 获取编译器并编译代码
// 由于我的代码使用了【自动属性】特性,所以需要 C# .3.5版本的编译器。
// 获取与CLR匹配版本的C#编译器可以这样写:CodeDomProvider.CreateProvider("CSharp") Dictionary<string, string> dict = new Dictionary<string, string>();
dict["CompilerVersion"] = "v3.5";
dict["WarnAsError"] = "false"; CSharpCodeProvider csProvider = new CSharpCodeProvider(dict);
CompilerResults cr = csProvider.CompileAssemblyFromSource(cp, code); // 4. 检查有没有编译错误
if( cr.Errors != null && cr.Errors.HasErrors ) {
foreach( CompilerError error in cr.Errors )
Console.WriteLine(error.ErrorText); return;
} // 5. 获取编译结果,它是编译后的程序集
Assembly asm = cr.CompiledAssembly;
整个过程分为5个步骤,它们已用注释标识出来了,这里不再重复了。
如何调用编译结果
前面的代码把一段文本字符串编译成了程序集,现在还有最后一个问题:如何调用编译结果?
答案:有二种方法,
1. 直接调用方法。
2. 实例化程序集中的类型,以接口方式调用方法。
其实这二种方法都需要使用反射,用反射定位到要调用的类型和方法。
第一种方法要求在生成代码时,生成的类名和方法名是明确的,在调用方法时,我们有二个选择:
1. 用反射的方式调用(这里只是一次反射)。
2. 为方法生成委托(用上篇博客介绍的方法),然后基于委托调用。
第二种方法要求在生成代码时,首先要定义一个接口,保证生成的代码能实现指定的接口,
然而用反射找到要调用的类型名称,用反射或者委托调用构造方法创建类型实例,最后基于接口去调用。
我们熟悉的ASPX页面就是采用了这种方式来实现的。
这二种方法也可以这样区分:
1. 如果生成的方法是静态方法,应该选择第一种方法。
2. 如果生成的方法是实例方法,那么选择第二种方法是合理的。
对于前面的示例,我采用了第一种方法了,因为类名和方法名称都是事先确定的而且实现起来比较简单。
// 6. 找到目标方法,并调用
Type t = asm.GetType("OptimizeReflection.用户手册");
MethodInfo method = t.GetMethod("Main");
method.Invoke(null, null);
参考:http://www.cnblogs.com/fish-li/archive/2013/02/24/2924673.html#_labelStart
如何将一段文本编译成C#内存程序的过程的更多相关文章
- C代码编译成可执行程序的过程
C代码通过编译器编译成可执行代码,经历了四个阶段,依次为:预处理.编译.汇编.链接. 接下来详细讲解各个阶段 一.预处理 1.任务:进行宏定义展开.头文件展开.条件编译,不检查语法. 2.命令:gcc ...
- Linux文本编译工具VIM详解
Linux文本编译工具VIM详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.VIM概述 1>.vim简介 >.vi: 全称Visual editor,即文本编辑 ...
- 实例具体解释:反编译Android APK,改动字节码后再回编译成APK
本文具体介绍了怎样反编译一个未被混淆过的Android APK,改动smali字节码后,再回编译成APK并更新签名,使之可正常安装.破译后的apk不管输入什么样的username和password都能 ...
- 关于.Net中Process的使用方法和各种用途汇总(二):用Process启动cmd.exe完成将cs编译成dll
上一章博客我为大家介绍了Process类的所有基本使用方法,这一章博客我来为大家做一个小扩展,来熟悉一下Process类的实际使用,废话不多说我们开始演示. 先看看我们的软件要设计成的布局吧. 首先我 ...
- 【CLR via C#】CSC将源代码编译成托管模块
下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模块(managedmod ...
- php 两段文本对比,不同的文字显示高亮
php 两段文本对比,不同的文字显示高亮[下面这个只能区分错误后面的..] <?php $str1 ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwgg ...
- C#如果把A.new()编译成new A()
缘由 对于初次接触某个第三方库的C#开发者,假如要调用里面一个方法,发现需要一个A类型的实例作为参数,怎么获得这个实例呢? 我想大多数人会先尝试new A吧: 如果没有,可能会尝试输入A.看看有没可能 ...
- [代码] 类似 YYText 将表情文本转换成表情字符
一,经历 1> 由于工作需要,得把 UITextView 中的属性文本转换成普通文字,并将处理后的普通文字转换成属性文本. 2> 将属性文本转换成普通文字简单,可以调用属性文本的enume ...
- 转 Flex MXML编译成AS类
2009-09-22 23:25 Flex MXML编译成AS类 由“Flex 基础”文中可知:每一个mxml文件首先要编译成as文件,然后再译成swf文件.app.mxml文件编译后会产生一系列中间 ...
随机推荐
- LSTM编程所用函数
1.Round函数返回一个数值,该数值是按照指定的小数位数进行四舍五入运算的结果.可是当保留位跟着的即使是5,有可能进位,也有可能舍去,机会各50% 2.python基础 (1)@property 特 ...
- [Unity优化]批处理02:动态批处理
参考链接: https://docs.unity3d.com/Manual/DrawCallBatching.html 原理: cpu每帧把可以进行动态批处理的网格进行合并,再把合并后的数据传给gpu ...
- thunderbird 163 smtp
thunderbird 163 smtp 如果要正常发送,配置如下: server: smtp.163.com port: 465 auth: Normal password security: SS ...
- Navicat操作SQL server 2008R2文件.bak文件还原
项目操作过程中,利用Navicat操作SQL Server2008R2数据备份,结果发现数据丢失了很多,不得不先对数据丢失部分进行差异对比,然后再重新输入. 1.利用Navicat导出的数据格式为sq ...
- orcal - 增删改
数据跟新 增删改 将emp复制到myemp CREATE TABLE myemp AS SELECT * FROM emp; 新增: INSERT INTO 表名称[(列名称1,列名称2,.....) ...
- C++_注释、枚举、typedef
#include<iostream> //using namespace std; int main() { /* ************************************ ...
- random模块的学习
import random # ret = random.random() #随机取0-1中间的浮点数 # ret = random.randint(1,3) #随机取1-3中间的整数 # ret = ...
- idea的环境设置
IDEA的个人配置与常用操作 IDEA的个人配置 1.修改代码编辑器 新版的IDEA默认使用vim编辑器(linux下的一个工具),虽然熟练掌握后可以提高工作效率,但是学习成本很大,不习惯的可以选择关 ...
- Swoft 容器使用
可以借助Swoft下的Bean类操作容器 示例: 将类绑定至容器 use Swoft\Bean\Annotation\Bean; /** * @Bean("imageLogic") ...
- join,left join,inner join,full join的区别?
left join(左联接) 返回包括左表中的所有记录和右表中联结字段相等的记录 right join(右联接) 返回包括右表中的所有记录和左表中联结字段相等的记录inner join(等值连接) 只 ...