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#内存程序的过程的更多相关文章

  1. C代码编译成可执行程序的过程

    C代码通过编译器编译成可执行代码,经历了四个阶段,依次为:预处理.编译.汇编.链接. 接下来详细讲解各个阶段 一.预处理 1.任务:进行宏定义展开.头文件展开.条件编译,不检查语法. 2.命令:gcc ...

  2. Linux文本编译工具VIM详解

    Linux文本编译工具VIM详解 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.VIM概述 1>.vim简介 >.vi: 全称Visual editor,即文本编辑 ...

  3. 实例具体解释:反编译Android APK,改动字节码后再回编译成APK

    本文具体介绍了怎样反编译一个未被混淆过的Android APK,改动smali字节码后,再回编译成APK并更新签名,使之可正常安装.破译后的apk不管输入什么样的username和password都能 ...

  4. 关于.Net中Process的使用方法和各种用途汇总(二):用Process启动cmd.exe完成将cs编译成dll

    上一章博客我为大家介绍了Process类的所有基本使用方法,这一章博客我来为大家做一个小扩展,来熟悉一下Process类的实际使用,废话不多说我们开始演示. 先看看我们的软件要设计成的布局吧. 首先我 ...

  5. 【CLR via C#】CSC将源代码编译成托管模块

    下图展示了编译源代码文件的过程.如图所示,可用支持 CLR 的任何一种语言创建源代码文件.然后,用一个对应的编译器检查语法和分析源代码.无论选用哪一个编译器,结果都是一个托管模块(managedmod ...

  6. php 两段文本对比,不同的文字显示高亮

    php 两段文本对比,不同的文字显示高亮[下面这个只能区分错误后面的..]   <?php $str1 ="MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwgg ...

  7. C#如果把A.new()编译成new A()

    缘由 对于初次接触某个第三方库的C#开发者,假如要调用里面一个方法,发现需要一个A类型的实例作为参数,怎么获得这个实例呢? 我想大多数人会先尝试new A吧: 如果没有,可能会尝试输入A.看看有没可能 ...

  8. [代码] 类似 YYText 将表情文本转换成表情字符

    一,经历 1> 由于工作需要,得把 UITextView 中的属性文本转换成普通文字,并将处理后的普通文字转换成属性文本. 2> 将属性文本转换成普通文字简单,可以调用属性文本的enume ...

  9. 转 Flex MXML编译成AS类

    2009-09-22 23:25 Flex MXML编译成AS类 由“Flex 基础”文中可知:每一个mxml文件首先要编译成as文件,然后再译成swf文件.app.mxml文件编译后会产生一系列中间 ...

随机推荐

  1. perl IDE

    学习perl的网站 网上学习perl教程,可以参考下面2个网站: 1.http://www.runoob.com/perl/perl-tutorial.html 2.https://cn.perlma ...

  2. flask同源策略解决办法及flask-cors只允许特定域名跨域

    falsk 同源策略解决办法: 使用 flask-cors 包 并且 在代码里 加响应的一行代码解决. from flask import Flask, session from flask_cors ...

  3. scrapy使用指南

    创建scrapy项目: scrapy startproject 项目名 cd到项目名下 scrapy genspider 爬虫名 www.baidu.com(网站网址) 之后按照提示创建爬虫文件(官方 ...

  4. 常见cmd命令,开发人员必备

    运行程序 notepad--------打开记事本 calc-----------启动计算器 regedit.exe-------注册表 write----------写字板 mmc--------- ...

  5. [解决]RESTEASY003215: could not find writer for content-type text/html type: java.lang.String

    一.问题描述 1)项目一开始采用JAX-RS 2.1+Jersey 2.26调用REST服务能正常调用并获得正确响应: 2)当项目引入dubbo 2.6.2后也用到rest而dubbo要用到RESTE ...

  6. 应用MySQL(开启远程登录权限)

    参考“开启MySQL远程访问权限 允许远程连接”.

  7. ASP.NET 实现PDF文件下载[转]

    本文介绍了一种在ASP.NET中下载文件的方法.方法一:可能是最简单的.最短的方式: 1 Response.ContentType = "application/pdf"; 2 R ...

  8. leetcode971

    class Solution: def flipMatchVoyage(self, root, voyage): res = [] self.i = 0 def dfs(root): if not r ...

  9. 基于C/S 结构的IM即时通讯软件--下篇

    3.实现界面事件函数 客户端:单击" 进入" 按钮发送请求,如果要与服务器通信,必须要同时发送结构体信息描述发送内容,便于服务器处理. void CCase010Dlg::OnBn ...

  10. a 标签实现分享功能

    在网页中,经常会用到分享功能,例如分享到qq,分享到微信,分享到微博等,但是怎么实现呢?一直没有想清楚这个问题,觉得好高大上的样子,于是在网上找了一些资料,也没有看出个什么所以然来: 于是有些心急了, ...