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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM