简单介绍编译C#代码

开发 后端
本文介绍编译C#代码,主要使用命名空间 Microsoft.CSharp 编译C#代码,然后使用 CodeDom 和 反射调用,我这里写了一个测试工具

编译C#代码应用场景:
还没想出来会用到哪里。动态的代码由谁来写?普通用户我想有一定的困难。特别是有了像 IronPython 这样更容易使用的动态嵌入脚本。
1) 像 LINQPad 这样的辅助开发工具
2) 实现脚本引擎?
3) 探讨...

主要使用命名空间 Microsoft.CSharp 编译C#代码,然后使用 CodeDom 和 反射调用,我这里写了一个测试工具,看代码:

  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.ComponentModel;  
  4. using System.Drawing;  
  5. using System.Windows.Forms;  
  6. using System.CodeDom.Compiler;  
  7. using Microsoft.CSharp;         // 用于编译C#代码    
  8. using System.Reflection;        // 用于反射调用   
  9. namespace CodeDomLearn  
  10. {  
  11. public partial class Form1 : Form  
  12. {  
  13. public Form1() {  
  14. InitializeComponent();  
  15.  
  16. }  
  17.  
  18. private void button1_Click(object sender, EventArgs e) {  
  19. CodeCompiler.Compile(new string[] { }, textBox1.Text, "");  
  20. listBox1.Items.Clear();  
  21. foreach (string s in CodeCompiler.ErrorMessage) {  
  22. listBox1.Items.Add(s);  
  23. }  
  24. listBox1.Items.Add(CodeCompiler.Message);  
  25. }  
  26. }  
  27.  
  28. static class CodeCompiler {  
  29. static public string Message;  
  30. static public List<string> ErrorMessage = new List<string>();  
  31.  
  32. public static bool Compile
    (string[] references, string source, string outputfile) {  
  33. // 编译参数    
  34. CompilerParameters param = new CompilerParameters
    (references, outputfile, true);  
  35. param.TreatWarningsAsErrors = false;  
  36. param.GenerateExecutable = false;  
  37. param.IncludeDebugInformation = true;  
  38.  
  39. // 编译    
  40. CSharpCodeProvider provider = new CSharpCodeProvider();  
  41. CompilerResults result = provider.CompileAssemblyFromSource
    (param, new string[] { source });  
  42.  
  43. Message = "";  
  44. ErrorMessage.Clear();  
  45. if (!result.Errors.HasErrors) { // 反射调用    
  46. Type t = result.CompiledAssembly.GetType("MyClass");  
  47. if (t != null) {  
  48. object o = result.CompiledAssembly.CreateInstance("MyClass");  
  49. Message = (string)t.InvokeMember("GetResult", BindingFlags.Instance | 
    BindingFlags.InvokeMethod | BindingFlags.Public, null, o, null);  
  50. }  
  51. return true;  
  52. }  
  53.  
  54. foreach (CompilerError error in result.Errors) {  // 列出编译错误  
  55. if (error.IsWarning) continue;  
  56. ErrorMessage.Add("Error(" + error.ErrorNumber + ") - " + error.ErrorText + 
    "\t\tLine:" + error.Line.ToString() + "  Column:"+error.Column.ToString());  
  57. }  
  58. return false;  
  59. }  
  60.  
  61. }  

作为演示,例子简单的规定类名必须是MyClass,必须有一个方法返回 string 类型的 GetResult 方法。以上介绍编译C#代码

【编辑推荐】

  1. C#反射方法学习总结
  2. 浅谈C#测量cpu性能
  3. C#远程计算机的一些理论知识
  4. 浅析C# Static修饰
  5. C#转换农历的简单方法
责任编辑:佚名 来源: Infoq
相关推荐

2009-09-01 10:35:19

C# 3.0编译器

2009-08-31 18:24:26

编译C#文件

2009-08-27 16:29:18

C#动态编译

2009-08-03 17:51:43

C#引用类型

2009-08-25 13:38:35

C# Timer组件

2009-08-20 16:25:59

C# 匿名方法

2009-08-06 18:15:13

C# SQL Serv

2009-08-07 17:12:07

C# DLL函数

2009-09-01 16:19:57

C# new()约束

2009-08-14 16:46:44

C#元数据

2009-09-03 09:40:57

C#创建表单

2009-08-10 16:19:37

C#冒泡排序

2009-08-06 14:53:41

C# User类

2009-08-21 17:55:52

C#复合控件

2009-08-14 17:27:56

C#方法参数

2009-08-07 17:41:40

C#预处理

2009-08-18 17:37:57

C#固定指针

2009-08-27 10:19:22

C#匿名类型

2009-08-14 11:34:26

Mono C#编译器

2009-08-06 14:59:36

C#编译器
点赞
收藏

51CTO技术栈公众号