C#即时编译器技术测试

用visual studio编写测试程序需要新建solution,然后project,命名和存盘都是麻烦事。可以考虑写一个自己的编译环境。
通过  Microsoft.CSharp.CSharpCodeProvider() 对象的 CompileAssemblyFromSource(parameters,codes) 方法就能得到编译结果对象 CompilerResults;然后结果对象再通过反射机制  result.CompiledAssembly.GetType("Phoenix") 就可以通过编译生成的程序集包含Main方法的类型。然后你可以 Phoenix.GetMethod("Main").Invoke(null,new string[]{});呼叫输出结果。

原理上说无非是构造csc可编译的完整源代码,然后生成assembly,当然是以临时文件形式存盘的,然后用reflect解析执行Main方法输出结果,如果用WinForm,可以用Console.SetOut重定向输出结果到控件。

测试代码如下,程序会编译文本 Console.WriteLine(\"Phoenix, from ashes it was born!\");:并给出结果!

 

using System;
using System.CodeDom.Compiler;


public  class MyClass
{
     private  static  string GenerateCode( string userCode)
    {
         string namespaces = @" using System;using System.ComponentModel;using System.Text;using System.Text.RegularExpressions;using System.IO;using System.Collections;using System.Collections.Generic;using System.Windows.Forms;using System.Threading;using System.Reflection; ";
         string codeHead =  @"
            sealed class Phoenix
            {
                public static void Main()
                {
";
                     // userCode here
         string codeTail =  @"
                }
            }
";        
         string compileCodes = namespaces + codeHead + userCode + codeTail;
         return compileCodes;
    }
    
     private  static CompilerResults Compile( string codes)
    {
         // CSharpCodeProvider
        System.CodeDom.Compiler.CodeDomProvider compiler =  new Microsoft.CSharp.CSharpCodeProvider();
         // CompilerParameters
        System.CodeDom.Compiler.CompilerParameters parameters =  new CompilerParameters();
        parameters.WarningLevel =  4;
        parameters.GenerateExecutable =  false;
        parameters.GenerateInMemory =  true;
        parameters.ReferencedAssemblies.Add( " System.dll ");
        parameters.ReferencedAssemblies.Add( " System.Windows.Forms.dll ");    
         // Compile: if successfully, we get the assembly with a temp filename    
         return compiler.CompileAssemblyFromSource(parameters,codes);
    }
    
     public  static  void Main()
    {
         string userCode =  " Console.WriteLine(\"Phoenix, from ashes it was born!\"); ";
         string compileCodes = GenerateCode(userCode);
         // Compile the codes and get the CompilerResults OBJECT
        System.CodeDom.Compiler.CompilerResults result = Compile(compileCodes);
        
         if(result.Errors.HasErrors)
        {
             // here, we output the error to output OBJECT
             foreach (CompilerError error  in result.Errors) {
                Console.WriteLine(error.Line +  " : " + error.ErrorText);
            }
            Console.ReadKey();
             return;
        }
         // output the result
        Console.WriteLine(result.CompiledAssembly.FullName);
        
        Type Phoenix = result.CompiledAssembly.GetType( " Phoenix ");
         try
        {
            Phoenix.GetMethod( " Main ").Invoke( null, new  string[]{});
        }
         catch(System.Reflection.TargetInvocationException ex)
        {
            Console.WriteLine(ex);
        }
        Console.ReadKey();
    }

}

 

 

 

你可能感兴趣的:(C#即时编译器技术测试)