动态编译执行C#代码

所谓动态代码执行,和脚本引擎有点类似。就是程序执行期从字符串或者文本文件中读取一段 C# 代码,在内存中动态编译成程序集,并创建相关类型实例执行相关方法。

具体的实现可参考下面的代码。如需要生成程序集文件,可参考 《使用CodeDom生成程序集》
using  System;
using  System.Reflection;
using  System.Globalization;
using  Microsoft.CSharp;
using  System.CodeDom;
using  System.CodeDom.Compiler;

namespace  ConsoleApplication1
{
  
public   class  Program
  {
    
static   void  Main( string [] args)
    {
      
//  定义需要动态执行的 C# 代码字符串,当然也可从文本文件中读取。
       string  code  =   @"
        using System;
        namespace MyNamespace
        {
          public class MyClass
          {
            private string name;

            public MyClass(string name)
            {
              this.name = name;
            }

            public void Test()
            {
              Console.WriteLine(""{0} - {1}"", name, DateTime.Now);
            }
          }
        }
      
" ;

      
//  创建编译器对象
      CSharpCodeProvider p  =   new  CSharpCodeProvider();
      ICodeCompiler cc 
=  p.CreateCompiler();

      
//  设置编译参数
      CompilerParameters options  =   new  CompilerParameters();
      options.ReferencedAssemblies.Add(
" System.dll " );
      options.GenerateInMemory 
=   true ;
      options.OutputAssembly 
=   " MyTest " ;
      
      
//  开始编译
      CodeSnippetCompileUnit cu  =   new  CodeSnippetCompileUnit(code);
      CompilerResults cr 
=  cc.CompileAssemblyFromDom(options, cu);

      
//  执行动态程序集相关内容。
      Type t  =  cr.CompiledAssembly.GetType( " MyNamespace.MyClass " );
      
object  o  =  cr.CompiledAssembly.CreateInstance( " MyNamespace.MyClass " false , BindingFlags.Default, 
        
null new   object [] {  " Tom "  }, CultureInfo.CurrentCulture,  null );
      t.InvokeMember(
" Test " , BindingFlags.Instance  |  BindingFlags.Public  |  BindingFlags.InvokeMethod, 
        
null , o,  null );

    }
  }
}
 

你可能感兴趣的:(动态编译)