2

NCalc の新機能。

評価する数式があり、(私にとって) 予期しない結果が得られます。

使用される @T_No_Starters パラメータ = 12。

数式が if (@T_No_Starters >= 8 ,'T','F') 結果 FALSEの場合

数式がif (@T_No_Starters >= 8.0 ,'T','F')結果TRUEの場合

数式がif (@T_No_Starters >= 10 ,'T','F')結果TRUEの場合

何が起こっているのかよくわかりません.なぜ 8 は False なのに 8.0 は True なのに 10 は True なのですか? 評価が常に正しいことを確認するにはどうすればよいですか? すべての数値を 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

数式の値を 10 進数に変更しないでください。8.0 以外の 8 スターター以上。それは正しく見えません。パラメータ ディクショナリは文字列と文字列で構成されています。一部は文字列であるため、使用する必要があります。値が必要なときにパラメーターが値であることを確認するのと同じくらい簡単ですか?

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 に答える