c# 动态编译类


前言

记录实现动态编译c# 类的方法


一、实现功能

在TextBox 中编写代码,例如实现弹窗显示计算累加和的结果。

在这里插入图片描述

二、实现步骤

1.添加控件

   添加1个 Texbox  及 Button.
   设置Texbox  属性,Multiline 设置为True. Text 设置为;

public byte TestFun()
{
byte a,b;
byte CalResult =0;
CalResult = CalculateSum(1,2);
MessageBox.Show(CalResult.ToString());
return CalResult ;
}

2.创建类

在....\bin\Debug 目录下,创建文件夹“DynamicCode” ,并在文件夹下创建类:类名为“DynamicCode”。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using WindowsFormsApp1;
using System.Windows.Forms;
using System.Security.Cryptography;

namespace WindowsFormsApp1
{
//代码执行类
class DynamicTestCode
{
public DynamicTestCode()
{

    }
    
    public static  byte CalculateSum(byte a, byte b)
    {
        byte c = 0;
        c = (byte)(a + b);
        return c;
    }
    /*PlaceHolder*/  //占位符(替换待运行的代码)

}

}

3.引入类

代码如下(示例):

using Microsoft.CSharp;               //
using System;
using System.CodeDom.Compiler;        //
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.IO;                      //
using System.Linq;
using System.Reflection;              //
using System.Text;
using System.Text.RegularExpressions; //
using System.Threading.Tasks;
using System.Windows.Forms;

4.编写实现动态编译的方法

代码如下(示例):

private bool TestCsCode()
        {
            string TestStr = null;
            string filePath = string.Format(@"{0}..\DynamicCode\", Application.StartupPath);

            filePath += "DynamicCode.cs";
            string strExpre = "";

            //计算/*PlaceHolder*/占位符的起始行数
            uint phStartLine = 1;
            using (StreamReader sw = new StreamReader(filePath))
            {
                strExpre = sw.ReadToEnd();
                string[] strExpreArray = strExpre.Split('\n');
                foreach (string item in strExpreArray)
                {
                    if (Regex.Match(item, @"\/\*PlaceHolder\*\/").Success)
                    {
                        break;
                    }
                    phStartLine++;
                }
                TestStr = this.txt_TestCode.Text;
                //PlaceHolder 用txt_TestCode 替换
                strExpre = Regex.Replace(strExpre, @"\/\*PlaceHolder\*\/", TestStr);
            }

            //1.创建CSharpCodeProvider的实例 (系统自带编译器)
            CSharpCodeProvider objCSharpCodePrivoder = new CSharpCodeProvider();        //编译器
            //2.创建一个ICodeComplier对象
            ICodeCompiler objICodeCompiler = objCSharpCodePrivoder.CreateCompiler();

            //3.创建一个CompilerParameters的实例
            CompilerParameters objCompilerParameters = new CompilerParameters();         //编译参数
            objCompilerParameters.GenerateInMemory = true;                               //设定在内存中创建程序集
            objCompilerParameters.GenerateExecutable = false;                            //设定是否创建可执行文件,也就是exe文件或者dll文件
            objCompilerParameters.ReferencedAssemblies.Add("System.dll");                //此处代码是添加对应dll文件的引用
            objCompilerParameters.ReferencedAssemblies.Add("System.Core.dll");           //System.Linq存在于System.Core.dll文件中
            objCompilerParameters.ReferencedAssemblies.Add("System.Windows.Forms.dll");
            string executingAssemblyLocation = Assembly.GetExecutingAssembly().Location;
            objCompilerParameters.ReferencedAssemblies.Add(executingAssemblyLocation);

            //4.创建CompilerResults的实例
            CompilerResults objCompilerResults = objICodeCompiler.CompileAssemblyFromSource(objCompilerParameters, strExpre);

            if (objCompilerResults.Errors.HasErrors)
            {
                Console.WriteLine("编译错误:1233");
                foreach (CompilerError err in objCompilerResults.Errors)
                {
                    Console.WriteLine(err.ErrorText);
                }
                return false;
            }
            else// MessageBox.Show("ddd");
            {
                try
                {
                    //5.创建一个Assembly对象(通过反射,调用 CalculateSum 的实例)
                    Assembly objAssembly = objCompilerResults.CompiledAssembly;                       //动态编译程序集
                    object objCsCode = objAssembly.CreateInstance("WindowsFormsApp1.DynamicTestCode"); //创建一个类实例对象
                    MethodInfo method = objCsCode.GetType().GetMethod("CalculateSum");                //获取对象的对应方法

                    byte a = 10;
                    byte b = 2;

                    byte CalculateResult = (byte)method.Invoke(objCsCode, new object[] { a, b });         //调用对象的方法
                    Console.WriteLine(CalculateResult);
                    byte i = 0;
                    //执行函数
                    //调用TestFun 函数实现功能
                    MethodInfo mi = objCsCode.GetType().GetMethod("TestFun");
                    byte result = (byte)mi.Invoke(objCsCode, new object[] { });
                    Console.WriteLine(result);      
                }
                catch (Exception e)
                {
                    //WriteLine(formatTestStepStr + e.Message);
                    Console.WriteLine(e.Message);
                    return false;
                }
            }
            return true;
        }

---

总结

实现c#类动态编译。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值