C#动态编译计算表达式的值

简介:

C#动态编译计算表达式的值,是通过System.CodeDom.Compiler命名空间下的相关类来实现的。其步骤大致为:

1.将表达式包装成为可编译的C#代码

2.使用反射调用上一步编译的代码。

示例如下:在界面上放一个TextBox,用来输入表达式;放一个按钮,用来相应用户点击,以进行表达式的计算;在另外一个TextBox中显示计算结果。对应的xaml代码如下:

复制代码
<Window x:Class="SampleCodeDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="403" Width="663" Loaded="Window_Loaded">
    <Grid>
        <TextBox Height="87" HorizontalAlignment="Left" Margin="12,12,0,0" Name="txtExpression" VerticalAlignment="Top" Width="617" TextWrapping="Wrap" />
        <Button Content="计算" Height="23" HorizontalAlignment="Left" Margin="554,114,0,0" Name="btnCalculate" VerticalAlignment="Top" Width="75" Click="btnCalculate_Click" />
        <TextBox Height="48" HorizontalAlignment="Left" Margin="12,157,0,0" Name="txtResult" VerticalAlignment="Top" Width="617" IsEnabled="False" TextWrapping="Wrap" />
    </Grid>
</Window>
复制代码

在后台代码中,首先添加一下引用:

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

剩余的代码如下:

复制代码
        private void Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.txtExpression.Focus();
        }

        private void btnCalculate_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string expression = this.txtExpression.Text.Trim();
                this.txtResult.Text = this.ComplierCode(expression).ToString();
            }
            catch (Exception ex)
            {
                this.txtResult.Text = ex.Message;
            }
        }

        private object ComplierCode(string expression)
        {
            string code = WrapExpression(expression);

            CSharpCodeProvider csharpCodeProvider = new CSharpCodeProvider();

            //编译的参数
            CompilerParameters compilerParameters = new CompilerParameters();
            //compilerParameters.ReferencedAssemblies.AddRange();
            compilerParameters.CompilerOptions = "/t:library";
            compilerParameters.GenerateInMemory = true;
            //开始编译
            CompilerResults compilerResults = csharpCodeProvider.CompileAssemblyFromSource(compilerParameters, code);
            if (compilerResults.Errors.Count > 0)
                throw new Exception("编译出错!");

            Assembly assembly = compilerResults.CompiledAssembly;
            Type type = assembly.GetType("ExpressionCalculate");
            MethodInfo method = type.GetMethod("Calculate");
            return method.Invoke(null, null);
        }

        private string WrapExpression(string expression)
        {
            string code = @"
                using System;

                class ExpressionCalculate
                {
                    public static DateTime start_dt = Convert.ToDateTime(""{start_dt}"");
                    public static DateTime end_dt = Convert.ToDateTime(""{end_dt}"");
                    public static DateTime current_dt = DateTime.Now;

                    public static object Calculate()
                    {
                        return {0};
                    }
                }
            ";

            return code.Replace("{0}", expression);
        }
复制代码

简单的说明一下,WrapExpression方法用来包装表达式,使其可以被代码编译器编译通过。ComplierCode方法用来编译,并通过反射执行代码。其它是两个事件的处理方法,无需多说。

在上面的示例中可以实现动态计算符合C#语法的数学表达式计算。

 

如果认为此文对您有帮助,别忘了支持一下哦!

作者: 齐飞
声明:本博客原创文字只代表本人工作中在某一时间内总结的观点或结论,与本人所在单位没有直接利益关系。非商业,未授权,贴子请以现状保留,转载时必须保留此段声明,且在文章页面明显位置给出原文连接。

转载:http://www.cnblogs.com/youring2/archive/2012/12/17/2822104.html
目录
相关文章
|
网络协议 关系型数据库 MySQL
MySQL 设置白名单的详细步骤
要为MySQL设置白名单,需要执行以下步骤: 1. 登录到MySQL服务器的命令行或图形界面客户端。 2. 选择要设置白名单的数据库。可以使用以下命令进入MySQL命令行界面: ``` mysql -u <username> -p ``` 3. 创建一个包含需要允许访问的IP地址的表。你可以使用以下命令进行创建: ``` CREATE TABLE whitelist ( id INT NOT NULL AUTO_INCREMENT, ip_address VARCHAR(45) NOT NULL, PRIMARY KEY (
3580 1
|
C# 图形学 C++
VS Code的插件市场
VS Code的插件市场
387 1
|
10月前
|
网络协议 应用服务中间件 网络安全
免费IP地址SSL证书在哪里申请
免费IP地址SSL证书的申请需通过特定的证书颁发机构(CA)或平台。JoySSL提供针对IP地址的免费SSL证书,Let&#39;s Encrypt则主要面向网站。申请步骤包括:访问官网注册账号(JoySSL需填写注册码230922),选择证书类型,填写信息并验证IP地址所有权,提交审核,下载部署证书。注意事项:确保IP地址有效、服务器支持HTTPS,并定期续签证书以保持有效性。
|
Ubuntu Linux
查看Linux系统架构的命令,查看linux系统是哪种架构:AMD、ARM、x86、x86_64、pcc 或 查看Ubuntu的版本号
查看Linux系统架构的命令,查看linux系统是哪种架构:AMD、ARM、x86、x86_64、pcc 或 查看Ubuntu的版本号
3351 4
|
7月前
|
存储 缓存 文件存储
uv安装python及其依赖的加速方法
国内在使用uv的时候,可能会涉及到装python的速度太慢的问题,为了解决这个问题,可以使用`UV_PYTHON_INSTALL_MIRROR`这个环境变量。除此以外,对于多人协作场景,`UV_CACHE_DIR`也是一个有用的环境变量。本文会介绍这两个变量。
5293 10
|
测试技术
软件测试高频面试题“黑盒测试之正交试验法”案例剖析与实践应用
软件测试高频面试题“黑盒测试之正交试验法”案例剖析与实践应用
732 0
|
缓存 负载均衡 JavaScript
服务器反向代理的作用与实现
服务器反向代理的作用与实现
490 8
|
监控 数据可视化 前端开发
高效设计企业营销系统的3种方案实践复盘
高效设计企业营销系统的3种方案实践复盘
350 2
|
存储 监控 持续交付
构建可扩展的阿里云 RPA 架构
随着企业业务的增长和变化,构建一个可扩展的机器人流程自动化(RPA)架构变得至关重要。本文将介绍如何利用阿里云 RPA 构建一个可扩展的架构,以适应不断变化的业务需求。
|
算法 搜索推荐 大数据
互联网信息服务算法备案代办服务
算法备案全称是什么?算法备案的全称为互联网信息服务算法备案,为应对不良深度合成技术而导致的算法歧视、大数据杀熟、沉迷推荐诱导等不合理应用,由网信办主导,与公安部、工信部、市监总局一起联合发布出台《互联网信息服务算法推荐管理规定》后的具有强制性的备案制度,旨在规范互联网信息服务推荐算法活动。