当前位置:  编程技术>.net/c#/asp.net

C#动态执行字符串(动态创建代码)的实例代码

    来源: 互联网  发布时间:2014-10-18

    本文导语:  代码如下:using System;using System.Data;using System.Configuration;using System.Text;using System.CodeDom.Compiler;using Microsoft.CSharp;using System.Reflection; namespace EvalGuy{    ///     /// 本类用来将字符串转为可执行文本并执行    /// 从别处复制,勿随...

代码如下:

using System;
using System.Data;
using System.Configuration;
using System.Text;
using System.CodeDom.Compiler;
using Microsoft.CSharp;
using System.Reflection;

namespace EvalGuy
{
    ///
    /// 本类用来将字符串转为可执行文本并执行
    /// 从别处复制,勿随意更改!
    ///
    public class Evaluator
    {
        #region 构造函数
        ///
        /// 可执行串的构造函数
        ///
        ///
        /// 可执行字符串数组
        ///
        public Evaluator(EvaluatorItem[] items)
        {
            ConstructEvaluator(items);        //调用解析字符串构造函数进行解析
        }
        ///
        /// 可执行串的构造函数
        ///
        /// 返回值类型
        /// 执行表达式
        /// 执行字符串名称
        public Evaluator(Type returnType, string expression, string name)
        {
            //创建可执行字符串数组
            EvaluatorItem[] items = { new EvaluatorItem(returnType, expression, name) };
            ConstructEvaluator(items);        //调用解析字符串构造函数进行解析
        }
        ///
        /// 可执行串的构造函数
        ///
        /// 可执行字符串项
        public Evaluator(EvaluatorItem item)
        {
            EvaluatorItem[] items = { item };//将可执行字符串项转为可执行字符串项数组
            ConstructEvaluator(items);        //调用解析字符串构造函数进行解析
        }
        ///
        /// 解析字符串构造函数
        ///
        /// 待解析字符串数组
        private void ConstructEvaluator(EvaluatorItem[] items)
        {
            //创建C#编译器实例
            ICodeCompiler comp = (new CSharpCodeProvider().CreateCompiler());
            //编译器的传入参数
            CompilerParameters cp = new CompilerParameters();

            cp.ReferencedAssemblies.Add("system.dll");                //添加程序集 system.dll 的引用
            cp.ReferencedAssemblies.Add("system.data.dll");            //添加程序集 system.data.dll 的引用
            cp.ReferencedAssemblies.Add("system.xml.dll");            //添加程序集 system.xml.dll 的引用
            cp.GenerateExecutable = false;                            //不生成可执行文件
            cp.GenerateInMemory = true;                                //在内存中运行

            StringBuilder code = new StringBuilder();                //创建代码串
            /*
             *  添加常见且必须的引用字符串
             */
            code.Append("using System; /n");
            code.Append("using System.Data; /n");
            code.Append("using System.Data.SqlClient; /n");
            code.Append("using System.Data.OleDb; /n");
            code.Append("using System.Xml; /n");

            code.Append("namespace EvalGuy { /n");                    //生成代码的命名空间为EvalGuy,和本代码一样

            code.Append("  public class _Evaluator { /n");            //产生 _Evaluator 类,所有可执行代码均在此类中运行
            foreach (EvaluatorItem item in items)                //遍历每一个可执行字符串项
            {
                code.AppendFormat("    public {0} {1}() ",            //添加定义公共函数代码
                                  item.ReturnType.Name,                //函数返回值为可执行字符串项中定义的返回值类型
                                  item.Name);                        //函数名称为可执行字符串项中定义的执行字符串名称
                code.Append("{ ");                                    //添加函数开始括号
                code.AppendFormat("return ({0});", item.Expression);//添加函数体,返回可执行字符串项中定义的表达式的值
                code.Append("}/n");                                    //添加函数结束括号
            }
            code.Append("} }");                                    //添加类结束和命名空间结束括号

            //得到编译器实例的返回结果
            CompilerResults cr = comp.CompileAssemblyFromSource(cp, code.ToString());

            if (cr.Errors.HasErrors)                            //如果有错误
            {
                StringBuilder error = new StringBuilder();            //创建错误信息字符串
                error.Append("编译有错误的表达式: ");                //添加错误文本
                foreach (CompilerError err in cr.Errors)            //遍历每一个出现的编译错误
                {
                    error.AppendFormat("{0}/n", err.ErrorText);        //添加进错误文本,每个错误后换行
                }
                throw new Exception("编译错误: " + error.ToString());//抛出异常
            }
            Assembly a = cr.CompiledAssembly;                        //获取编译器实例的程序集
            _Compiled = a.CreateInstance("EvalGuy._Evaluator");        //通过程序集查找并声明 EvalGuy._Evaluator 的实例
        }
        #endregion

        #region 公有成员
        ///
        /// 执行字符串并返回整型值
        ///
        /// 执行字符串名称
        /// 执行结果
        public int EvaluateInt(string name)
        {
            return (int)Evaluate(name);
        }
        ///
        /// 执行字符串并返回字符串型值
        ///
        /// 执行字符串名称
        /// 执行结果
        public string EvaluateString(string name)
        {
            return (string)Evaluate(name);
        }
        ///
        /// 执行字符串并返回布尔型值
        ///
        /// 执行字符串名称
        /// 执行结果
        public bool EvaluateBool(string name)
        {
            return (bool)Evaluate(name);
        }
        ///
        /// 执行字符串并返 object 型值
        ///
        /// 执行字符串名称
        /// 执行结果
        public object Evaluate(string name)
        {
            MethodInfo mi = _Compiled.GetType().GetMethod(name);//获取 _Compiled 所属类型中名称为 name 的方法的引用
            return mi.Invoke(_Compiled, null);                    //执行 mi 所引用的方法
        }
        #endregion

        #region 静态成员
        ///
        /// 执行表达式并返回整型值
        ///
        /// 要执行的表达式
        /// 运算结果
        static public int EvaluateToInteger(string code)
        {
            Evaluator eval = new Evaluator(typeof(int), code, staticMethodName);//生成 Evaluator 类的对像
            return (int)eval.Evaluate(staticMethodName);                        //执行并返回整型数据
        }
        ///
        /// 执行表达式并返回字符串型值
        ///
        /// 要执行的表达式
        /// 运算结果
        static public string EvaluateToString(string code)
        {
            Evaluator eval = new Evaluator(typeof(string), code, staticMethodName);//生成 Evaluator 类的对像
            return (string)eval.Evaluate(staticMethodName);                        //执行并返回字符串型数据
        }
        ///
        /// 执行表达式并返回布尔型值
        ///
        /// 要执行的表达式
        /// 运算结果
        static public bool EvaluateToBool(string code)
        {
            Evaluator eval = new Evaluator(typeof(bool), code, staticMethodName);//生成 Evaluator 类的对像
            return (bool)eval.Evaluate(staticMethodName);                        //执行并返回布尔型数据
        }
        ///
        /// 执行表达式并返回 object 型值
        ///
        /// 要执行的表达式
        /// 运算结果
        static public object EvaluateToObject(string code)
        {
            Evaluator eval = new Evaluator(typeof(object), code, staticMethodName);//生成 Evaluator 类的对像
            return eval.Evaluate(staticMethodName);                                //执行并返回 object 型数据
        }
        #endregion

        #region 私有成员
        ///
        /// 静态方法的执行字符串名称
        ///
        private const string staticMethodName = "__foo";
        ///
        /// 用于动态引用生成的类,执行其内部包含的可执行字符串
        ///
        object _Compiled = null;
        #endregion
    }
    ///
    /// 可执行字符串项(即一条可执行字符串)
    ///
    public class EvaluatorItem
    {
        ///
        /// 返回值类型
        ///
        public Type ReturnType;
        ///
        /// 执行表达式
        ///
        public string Expression;
        ///
        /// 执行字符串名称
        ///
        public string Name;
        ///
        /// 可执行字符串项构造函数
        ///
        /// 返回值类型
        /// 执行表达式
        /// 执行字符串名称
        public EvaluatorItem(Type returnType, string expression, string name)
        {
            ReturnType = returnType;
            Expression = expression;
            Name = name;
        }
    }
}


    
 
 

您可能感兴趣的文章:

  • Linux下c函数dlopen实现加载动态库so文件代码举例
  • 使用 C# 动态编译代码和执行的代码
  • jquery为动态加载的元素绑定事件的代码
  • 不改变代码,怎样使每次编译生成的可执行程序或动态库二进制保持一致?
  • c# 动态添加非标准html控件的代码
  • ?100分求jsp树的原代码 最好是jsp+js+xml 执行效率要高。(从数据库中动态生成的)(散分)
  • Unix里编写动态库时会不会像Windows一样在源代码中含有Dllmain()类似的主函数?
  • 急,急,急!!!高分求购java实现动态树型菜单的源代码
  • jquery动态设置超链接显示内容的实现代码
  • Jquery 动态实现图片缩略的代码
  • 用css动态生成闪字的代码
  • 100分求jsp树的原代码 最好是jsp+js+xml 执行效率要高。(从数据库中动态生成的)在线
  • ThinkPHP3.1新特性之动态设置自动完成及自动验证示例代码
  • 求jsp树的原代码,一定要是jsp+js+xml 执行效率要高。(从数据库中动态生成的)
  • 动态生成的孔件怎么添加响应事件,并在里面写代码?
  • 动态创建类实例代码
  • jQuery动态获取系统时间的代码举例
  • php 饼状图的动态生成代码
  • jquery动态加载与去除js代码的三种方法
  • Java动态调用类中方法代码
  • Jquery 动态生成表格示例代码
  • C#实现动态显示及动态移除图片方法
  • C#实现动态生成表格的方法
  • C#中事件的动态调用实现方法
  • c# DataGridView动态添加新行的二个方法
  • c#动态加载卸载DLL的方法
  • C#在运行时动态创建类型的实现方法
  • c#动态编译执行对象方法示例 运用映射机制创建对象
  • c#动态改变webservice的url访问地址
  • C#中动态显示当前系统时间的实例方法
  • c# asp .net 动态创建sql数据库表的方法
  •  
    本站(WWW.)旨在分享和传播互联网科技相关的资讯和技术,将尽最大努力为读者提供更好的信息聚合和浏览方式。
    本站(WWW.)站内文章除注明原创外,均为转载、整理或搜集自网络。欢迎任何形式的转载,转载请注明出处。












  • 相关文章推荐
  • linux下c++对长度不定的字符串要进行预先动态分配内存需要怎么做?
  • Java 将字符串动态生成字节码的实现方法
  • 再问: 极具挑战性的问题:动态申请内存,再用来存储二维字符串数组
  • 极具挑战性的问题:动态申请内存,再用来存储二维字符串数组
  • 动态字符串库 SDS
  • Linux下指定运行时加载动态库路径及shell下执行程序默认路径
  • 可执行程序加载动态库 和 动态库加载动态库 的动态库初始化的问题
  • 动态库调用动态库
  • linux动态链接库里全局变量和静态变量会导致动态库不可重入吗?
  • linux能否成为动态域名解析客户端的动态域名解析服务器?
  • 关于动态菜单项,注意,不是动态菜单(一定给分)
  • Linux下,怎么确定动态库的绝对位置(动态库里面确定)?
  • 为什么动态生成的图片,JSP不能动态的获得
  • 请问:能不能动态的运行时生成对象(动态定义对象), 要涉及到哪些技术, 反射,序列化...??
  • 动态加载动态库问题--在线等
  • 静态库,动态库,静态链接和动态链接
  • 在linux下(c++),如何动态调用 动态库(.so)? 为什么我编译报错:undefined reference to "dlopen"
  • 程序发布的问题(动态连接库的问题)
  • JSP动态缓存 JimStoneCache
  • 怎么调试unix动态库.
  • 如何调用动态
  • 动态编译与静态编译驱动程式疑问?
  • 关于动态库的问题,谢谢!
  • linux动态路由问题
  • 内核与动态(共享)库
  • Linux 动态库,静态库的一些疑惑


  • 站内导航:


    特别声明:169IT网站部分信息来自互联网,如果侵犯您的权利,请及时告知,本站将立即删除!

    ©2012-2021,,E-mail:www_#163.com(请将#改为@)

    浙ICP备11055608号-3