• C#实现任意大数的计算和简单逻辑命题的证明——前言


    介绍

    这是本人毕业设计的项目,一直想将其整理成文,可一不小心4年就过去了(这个时间又可以读个大学了)。现在给自己定一个目标,一个月时间里将项目的所有关键点都整理出来。不然真怕一眨眼又一个4年过去了,而代码依然躺在硬盘里。

    项目取名MathAssist,使用vs2008。分成四个子项目:

    1. MathAssistLibrary    提供一个接口,以便实现用dll拓展的插件机制
    2. SuperCalculator   实现任意大数计算的插件
    3. 命令证明              实现简单逻辑命题证明的插件
    4. MathAssist          主程序,会扫描并加载其路径下所有符合条件的dll

    其主程序可以从插件中扫描可用的命令,也可以显示插件中可用的窗体。如下是主程序界面,其加载了两个插件:“superCalculator”和“命令证明”。它们分别提供命令cal prove。

    点击菜单项"插件"的子菜单后可以分别打开两个插件中实现的窗口。如下图

    分别实现了大数计算和逻辑命题的证明。

    在这篇前言中就先只介绍插件机制的实现吧,大数计算和逻辑命题的证明就留给后面的系列。

    插件机制的实现

    MathAssistLibrary接口的定义

    在MathAssistLibrary项目中只定义了两个接口: ICommand, IForm,分别用于提供命令行功能和窗口功能。

     1     /// <summary>命令接口</summary>
     2     public interface ICommand
     3     {
     4         /// <summary>命令名称</summary>
     5         string Name { get; }
     6 
     7         /// <summary>执行命令</summary>
     8         /// <param name="cmd">命令参数</param>
     9         /// <returns>返回的结果</returns>
    10         string Excute( string cmd );
    11 
    12         /// <summary>对命令的使用作相应的说明</summary>
    13         string Describe { get; }
    14     }
    15     /// <summary>获得插件的窗体</summary>
    16     public interface IForm
    17     {
    18         /// <summary>窗体名</summary>
    19         string Text { get; }
    20 
    21         /// <summary>窗体对象</summary>
    22         Form GetForm { get; }
    23     }
    MathAssistLibrary

    ICommand接口

    • Name 用于表示命令的名称
    • Excute 用于执行命令
    • Describe 用于对这个命令提供一个简要的帮助文档说明

    IForm接口

    • Text 用于表示窗体的名称
    • GetForm 用于获取Form对象。在主程序中获取Form对象后,再调用Show()即可显示之。

    插件实现

    在插件项目中只要实现ICommand和IForm两个接口即可,以SuperCalculator为例:

    public partial class frmSuperCalculator : Form, IForm
    {
            string IForm.Text {
                get { return "计算器"; }
            }
    
            frmSuperCalculator frm;
            Form IForm.GetForm {
                get {
                    if (frm == null || frm.IsDisposed) {
                        frm = new frmSuperCalculator();
                    }
                    return frm;
                }
            }
            ...  
    }
    public class Calculator : MathAssistLibrary.ICommand
    {
            string MathAssistLibrary.ICommand.Describe {
                get { return "cal命令可以进行相关的数学运算。比如cal 1+max(2,3)*2"; }
            }
            string MathAssistLibrary.ICommand.Name {
                get { return "cal"; }
            }
            string MathAssistLibrary.ICommand.Excute(string cmd) {
                try {
                    Expression exp = new Expression();
                    exp.Format = cmd;
                    return exp.Calculator().ToString();
                } catch (ExpressionException e) {
                    return string.Format("表达式出错。出错类型:{0},出错位置{1}", e.Message, e.Index);
                }
            }
    }

    主程序对插件的扫描

    FindDllFile()函数找到与程序同路径下的所有dll文件,代码如下:

     1         List<string> FindDllFile(string foldername) {
     2             DirectoryInfo dir = new DirectoryInfo(foldername);
     3             FileInfo[] files = dir.GetFiles();
     4             List<string> result = new List<string>();
     5 
     6             foreach (FileInfo fi in files) {
     7                 if (fi.Name.ToUpper().EndsWith(".DLL"))
     8                     result.Add(fi.FullName);
     9             }
    10             return result;
    11         }
    FindDllFile

    LoadOne()从一个文件中找一个特定的类型,并返回其对象,代码如下:

            private List<object> LoadOne(string filename, Type type) {
                List<object> result = new List<object>();
    
                try {
                    Assembly ass = Assembly.LoadFrom(filename);
                    Module[] mods = ass.GetModules();
    
                    foreach (Module mod in mods) {
                        Type[] typs = mod.GetTypes();
    
                        foreach (Type typ in typs) {
                            if (type.IsAssignableFrom(typ)) {
                                result.Add(ass.CreateInstance(typ.FullName));
                            }
                        }
                    }
                } catch (BadImageFormatException) {
    
                }
                return result;
            } // end func

     先用Assembly.LoadFrom()加载程序集,然后获取所有模块,最后在所有模块中用type.IsAssignableFrom()找与传入参数type相匹配的类型,如果匹配那么就创建一个对象并返回。

    在主程序中分别用如下两行代码调用LoadOne() 

    List<object> cmd = LoadOne(filename, typeof(ICommand));
    List<object> frm = LoadOne(filename, typeof(IForm));

     这样用cmd.Excute()就可以执行插件中实现的代码,用frm.Show()就可以显示插件中所实现的窗体。

    现提供MathAssist.exe的下载路径。在后面的文章中会给出整个程序的源码,敬请期待~~

     参数文献:  http://www.cnblogs.com/conexpress/archive/2009/03/04/MyCalculator_01.html

  • 相关阅读:
    精彩的“利益均衡”,尤其是“四”
    用搭积木的方式开发
    从公司层面看信息管理中的问题
    广义信息结构
    Cephfs创建及挂载
    对各类术语表进行记录
    weixin报警脚本
    shell 实现mysql写入操作
    python生成图片
    python实现路由追踪,并生成追踪图片
  • 原文地址:https://www.cnblogs.com/xiangism/p/4593128.html
Copyright © 2020-2023  润新知