天天看點

【awesome-dotnet-core-learning】(2)-Sprache.Calc-表達式電腦

【awesome-dotnet-core-learning】(2)-Sprache.Calc-表達式電腦

示例代碼托管在GITHUB上, 歡迎STAR!

嚴格來說, Sprache.Calc隻是上一篇Sprache-解析器建構庫中介紹的Sprache的一個擴充庫,而且未羅列在awesome-dotnet-core中.但是表達式計算在很多應用中都有需求,是以單獨寫一篇部落格介紹它.

簡介

Sprache.Calc提供了簡單易用的表達式電腦功能.可将輸入的字元串做為一個表達式,轉換成結構化的LINQ表達式,并且可被編譯為可執行的委托.

特點

  • 支援算術運算, 自定義函數和參數
  • 轉換為LINQ表達式
  • 可編譯成委托并執行
  • 因為可編譯成委托,是以性能上與原生C#相同

快速上手

以下示例示範了用Sprache.Calc編寫一個計算表達式的程式.并示範了自定義函數和參數的使用方法.

  1. 建立一個.NET Core的指令行應用程式(詳細步驟略)
  2. 使用Nuget安裝Sprache.Calc:
    Install-Package Sprache.Calc
               
  3. Program.cs

    中,首先建立一個表達式電腦:
    private static readonly XtensibleCalculator Calculator = new XtensibleCalculator();
               
  4. 編寫一個輔助方法,用于編譯,執行輸入的文本,并輸出結果
    /// <summary>
    /// 運作表達式,輸出計算結果
    /// </summary>
    /// <param name="text">文本</param>
    /// <param name="parameters">參數</param>
    private static void RunExpression(string text, params Expression<Func<double, double>>[] parameters)
    {
        var expr = Calculator.ParseExpression(text, parameters);
        var func = expr.Compile();
        Console.WriteLine($"{text} = {func()}");
    }
               
    首先使用XtensibleCalculator的

    ParseExpression

    方法解析文本表達式, 該方法傳回值為

    Expression<Func<double>>

    類型.是以可以使用

    Compile

    方法繼承編譯為

    Func<double>

    , 最後直接執行即可得到計算結果.

    parameters

    用于接收表達式中的參數.每一個都是一個

    Func<double, double>

    類型委托,如沒有參數,可不傳遞.
  5. Main

    方法中,就可調用

    RunExpression

    了,首先我們測試基本的四則運算:
    // 四則運算
    RunExpression("1 + 2 * 3");
    RunExpression("(1 + 2) * 3");
               
    輸出結果:
    1 + 2 * 3 = 7
    (1 + 2) * 3 = 9
               
    可注意到運算符的優先級和括号都是支援的.
  6. 測試自定義函數:
    // 自定義函數
    // 這裡注冊了一個名為"階乘"的函數,用來計算一個數的階乘
    Calculator.RegisterFunction("階乘", n =>
    {
        // n的階乘 = n * (n-1) * (n-2) * ... * 1
        int r = 1;
        for (int i = (int) n; i > 0; i--) r *= i;
        return r;
    });
    RunExpression("階乘(3) + 階乘(4)");
               
    我們通過

    RegisterFunction

    方法注冊了一個名為"階乘"的函數(是的自定義函數名可以為中文),然後通過Lambda函數提供了計算邏輯.這樣在表達式中就可以使用我們的自定義函數了.
    階乘(3) + 階乘(4) = 30
               
  7. 測試參數
    // 參數
    RunExpression("階乘(a) + 階乘(b)", a => 4, b => 5); // 将4代入a, 5代入b
               
    我們将表達式中的參數,通過lambda表達式指派,這樣在運作時,該參數的值就會參與計算了.
    階乘(a) + 階乘(b) = 144
               

類似庫

  • loresoft/Calculator
  • etsync/NCalcsec

繼續閱讀