2

全新的 NCalc。

我有一个要评估的公式,我得到了一些意想不到的(对我来说)结果。

使用的 @T_No_Starters 参数 = 12。

如果公式为 if (@T_No_Starters >= 8 ,'T','F') Result FALSE

如果公式if (@T_No_Starters >= 8.0 ,'T','F')结果为 TRUE

如果公式if (@T_No_Starters >= 10 ,'T','F')结果为 TRUE

我不确定发生了什么,为什么 8 为假而 8.0 为真但 10 又是一个整数是真?如何确保评估始终正确?我要把每个数字都变成十进制吗?我可以设置参数类型之类的东西吗?当我输入我的参数?

下面是我用来达到上述目标的测试代码。

Private Sub Button40_Click(sender As Object, e As EventArgs) Handles Button40.Click
        Dim FormulaLine As String = "if (@T_No_Starters >= 8 ,'T','F')"

        Dim Parms As New Dictionary(Of String, String)
        Parms.Add("T_No_Starters", 12)
        Dim OurAnswer = FormulaCalculator.MSGBOXEval(FormulaLine, Parms)
    End Sub

Function MSGBOXEval(Formula As String, Parms As Dictionary(Of String, String))

        Try
            Dim X As New Expression(Formula)
            For Each key As String In Parms.Keys
                X.Parameters.Add(key, Parms.Item(key))
            Next

            Dim result = X.Evaluate
            MessageBox.Show(result)
            Return result
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Return "Error " & ex.Message
        End Try

        Return 0
    End Function

我最好不要将公式中的值更改为十进制。大于或等于 8 个启动器而不是 8.0。只是看起来不太对。参数字典是字符串和字符串,我必须使用它,因为有些是字符串。是否像在需要值时确保参数是值一样简单?

4

1 回答 1

2

这是一个很晚的答案,但我将其发布给未来的读者。

您的字典由字符串组成:

Dim Parms As New Dictionary(Of String, String)

原始参数类型无关紧要,VB将为您转换为字符串:

Parms.Add("T_No_Starters", 12)

它相当于:

Parms.Add("T_No_Starters", "12")

现在很明显,您正在将参数添加为字符串:

Dim X As New Expression(Formula)
For Each key As String In Parms.Keys
    X.Parameters.Add(key, Parms.Item(key))
Next

NCalc 将尝试转换类型并评估表达式而不会出错:

if (@T_No_Starters >= 8 ,'T','F')

它相当于:

if (@T_No_Starters >= '8' ,'T','F')

因为它是一个字符串比较(没有自然顺序),所以'12' >= '8'是正确的FALSE(其他例子也变得合理)。

你应该怎么做?只需更改字典的类型以避免任何隐式转换,让 NCalc 为您执行此操作:

Dim Parms As New Dictionary(Of String, Object)

和:

Function MSGBOXEval(Formula As String, Parms As Dictionary(Of String, Object))

请注意,使用 Object 您仍然可以将任何类型添加到字典中:

Params.Add("T_Text", "some text") 
Params.Add("T_Beginning", DateTime.Now)
于 2015-09-08T07:53:52.050 回答