3

I have no idea how I'm going to accomplish this BUT someway, somehow I have to perform calculations dynamically in ASP/VB.NET (Possibly SQL Server). Something like this:

Dim var1, var2 as Integer
Dim Optr as string

var1 = 15
var2 = 25
Optr = +

MyResult(var1, var2, Optr) 

...and MyResult should equal 40. How can I do this? Anyone have any ideas? Thanks!

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
  • 2
    This would be very easy IF `Optr` were a string literal, such as: `Optr = "+"`, because then you just have a switch/case that handles all possible operators... – FrustratedWithFormsDesigner Apr 29 '11 at 15:22
  • Optr should be whatever the .NET equivalent of a function pointer is. Then it can just be assigned to the desired function. – phkahler Apr 29 '11 at 15:26

4 Answers4

0

To allow for arbitrarily complex calculations you could take advantage of .NET's on-fly-compilation features. Here's an article for starters.

For your particular implementation you would construct a calculation string from your input like this:

Dim toCalc as string = var1 & " " & Optr & " " & var2

...and use a process where the calculation would get injected into a dynamically created class that would look something like this: (working console sample based on the CP article)

Imports System.CodeDom.Compiler
Imports System.Reflection

Module Module1
    Sub Main()
        Dim var1 As Integer = 50
        Dim var2 As Integer = 65
        Dim Optr As String = "+"
        Dim equation As String = var1 & " " & Optr & " " & var2
        Dim nl As String = System.Environment.NewLine

        Dim dynClass As String = ""
        dynClass &= "public class DynamicClass" & nl
        dynClass &= "   public shared function Calc() as double" & nl
        dynClass &= "       return " & equation & nl
        dynClass &= "   end function" & nl
        dynClass &= "end class" & nl

        Try
            Dim params As New CompilerParameters
            params.ReferencedAssemblies.AddRange(New String() {"Microsoft.VisualBasic.dll"})

            Dim mAssembly As Assembly = New VBCodeProvider().CreateCompiler. _
                CompileAssemblyFromSource(params, dynClass).CompiledAssembly

            Console.WriteLine("Calculating: " & equation)
            Console.WriteLine("SUCCESS! Result: " & mAssembly. _
                    GetType("DynamicClass"). _
                    InvokeMember("Calc", _
                    BindingFlags.InvokeMethod Or _
                    BindingFlags.Public Or _
                    BindingFlags.Static, _
                    Nothing, Nothing, Nothing).ToString())
        Catch ex As Exception
            Console.WriteLine(ex.Message)
        End Try
    End Sub
End Module
Paul Sasik
  • 79,492
  • 20
  • 149
  • 189
0

I don't have the code specifics, but you if have your vars and operations concatenated as a single string you could parse the string and compile it, given you the proper result.

Check this SO questions and answers here, they discuss a very similar problem (if not the exact same)

Community
  • 1
  • 1
mcabral
  • 3,524
  • 1
  • 25
  • 42
0

The only way I can think of is a switch case which deals with all possible operators.

If you want to implement something more complicated(with operator presedence) you can use the Shunting Yard Algorithm

Afiefh
  • 920
  • 1
  • 7
  • 15
  • This one was the quickest workaround, although I did like the other ideas. Unfortunately, I had a time constraint. –  May 02 '11 at 15:37
0

I like Paul Sasik's example for a purely .net solution, but another alternative would be to make use of the VBScript engine that's part of windows.

For example (you'll need to add a reference to the COM MSScript control)

    Static sc As MSScriptControl.ScriptControl

    '---- init the script control once
    If sc Is Nothing Then
        sc = New MSScriptControl.ScriptControl
        sc.Language = "VBScript"
        sc.AllowUI = False
    End If

    Try
        Return sc.Eval(Expr)
    Catch ex As Exception
        'Deal with any error conditions here
    End Try

Where Expr is any expression you might want to evaluate.

Granted, this leverages VBScript support, which you might want to avoid, but, depending on your audience, they might be more comfortable with that than .net coding

DarinH
  • 4,868
  • 2
  • 22
  • 32
  • +1 Nice alternative. Would this work out of C# as well or does VB.NET have some particualr hooks? – Paul Sasik Apr 29 '11 at 18:44
  • No. nothing special for VB. The MSScript control is just a plain ol' active dll, so you can reference it from a .net project pretty straightforwardly. Should work basically the same from C#. – DarinH Apr 29 '11 at 18:54
  • Another thing to point out with this approach is I believe the old ms javascript implementation is in that scripting library as well. I haven't worked with it specifically, but I'm pretty sure if you wanted to support Javascript rather than VBScript, it'd do it with just a property change. – DarinH Apr 29 '11 at 18:55