zoukankan      html  css  js  c++  java
  • 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#语法的数学表达式计算。

  • 相关阅读:
    首页列表显示全部问答,完成问答详情页布局。
    制作首页的显示列表。
    管理信息系统 课程设计
    期末作品检查
    数据迁移
    模型分离(选做)
    密码保护
    实现搜索功能
    完成个人中心—导航标签
    个人中心标签页导航
  • 原文地址:https://www.cnblogs.com/youring2/p/2822104.html
Copyright © 2011-2022 走看看