1. 程式人生 > >c# 動態編譯程式碼

c# 動態編譯程式碼

有時候做計算一些東西時候,演算法一直變更,寫在程式需要一直調整,因此演算法寫在cs檔案,然後動態呼叫內部的方法去計算判斷,只需變更cs檔案即可。

using Microsoft.CSharp;
using System;
using System.CodeDom.Compiler;
using System.Diagnostics;
using System.IO;
using System.Reflection;

namespace ConsoleApplication
{
    class Program
    {
        static void Main()
        {
            Stopwatch watch = new Stopwatch();
            watch.Start();
            //建立一個CSharp語言Provider
            //CodeDomProvider provider = CodeDomProvider.CreateProvider("CSharp");
            CSharpCodeProvider provider = new CSharpCodeProvider();
            watch.Stop();
            Console.WriteLine("建立耗時:" + watch.ElapsedMilliseconds);

            watch.Restart();
            //設定編譯時引數
            CompilerParameters objCompilerParameters = new CompilerParameters();
            //新增程式碼用到的相關引用
            objCompilerParameters.ReferencedAssemblies.Add("System.dll");
            //沒有Main函式就不能生成可執行檔案
            objCompilerParameters.GenerateExecutable = false;
            objCompilerParameters.GenerateInMemory = true;
            watch.Stop();
            Console.WriteLine("設定編譯引數耗時:" + watch.ElapsedMilliseconds);

            watch.Restart();
            //編譯程式碼
            string code = File.ReadAllText(AppDomain.CurrentDomain.BaseDirectory + "Class1.cs");
            CompilerResults cr = provider.CompileAssemblyFromSource(objCompilerParameters, code);
            watch.Stop();
            Console.WriteLine("編譯耗時:" + watch.ElapsedMilliseconds);

            if (cr.Errors.HasErrors)
            {
                Console.WriteLine("編譯錯誤:");
                foreach (CompilerError err in cr.Errors)
                {
                    Console.WriteLine(err.ErrorText);
                }
            }
            else
            {
                watch.Restart();
                // 通過反射,呼叫HelloWorld的例項
                object objHelloWorld = cr.CompiledAssembly.CreateInstance("ConsoleApplication.Class1");
                MethodInfo objMI = objHelloWorld.GetType().GetMethod("test");
                Console.WriteLine(objMI.Invoke(objHelloWorld, null));
                watch.Stop();
                Console.WriteLine("呼叫耗時:" + watch.ElapsedMilliseconds);
            }
            Console.ReadLine();
        }
    }
}
 

 

被呼叫的cs檔案內容

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApplication
{
    class Class1
    {
        //寫個方法測試下動態呼叫的情況
        public void test()
        {
            DateTime now = DateTime.Now;

            List<string> aa = new List<string>();
            aa.Add("aa");
            Console.WriteLine(now);
        }
    }
}

 

參考地址:http://www.cnblogs.com/jailu/archive/2007/07/22/827058.html