Imports System.CodeDom.Compiler
Imports System.Reflection
Module Module1
Private Function ProcessCommand(ByVal command As String) As Double
Dim MyProvider As New VBCodeProvider 'Create a new VB Code Compiler
Dim cp As New CompilerParameters 'Create a new Compiler parameter object.
cp.GenerateExecutable = False 'Don't create an object on disk
cp.GenerateInMemory = True 'But do create one in memory.
'If cp.OutputAssembly is used with a VBCodeProvider, it seems to want to read before it is executed.
'See C# CodeBank example for explanation of why it was used.
'the below is an empty VB.NET Project with a function that simply returns the value of our command parameter.
Dim TempModuleSource As String = "Imports System" & Environment.NewLine & _
"Namespace ns " & Environment.NewLine & _
"Public Class class1" & Environment.NewLine & _
"Public Shared Function Evaluate()" & Environment.NewLine & _
"Return " & command & Environment.NewLine & _
"End Function" & Environment.NewLine & _
"End Class" & Environment.NewLine & _
"End Namespace"
'Create a compiler output results object and compile the source code.
Dim cr As CompilerResults = MyProvider.CompileAssemblyFromSource(cp, TempModuleSource)
If cr.Errors.Count > 0 Then
'If the expression passed is invalid or "", the compiler will generate errors.
Throw New ArgumentOutOfRangeException("Invalid Expression - please use something VB could evaluate")
Else
'Find our Evaluate method.
Dim methInfo As MethodInfo = cr.CompiledAssembly.GetType("ns.class1").GetMethod("Evaluate")
'Invoke it on nothing, so that we can get the return value
Return Convert.ToDouble(methInfo.Invoke(Nothing, Nothing))
End If
End Function
Sub Main()
Console.WriteLine(ProcessCommand("1+1").ToString()) 'Displays 2
Console.WriteLine(ProcessCommand("Math.PI").ToString()) 'Displays 3.14159265358979
Console.WriteLine(ProcessCommand("Math.Abs(-22)").ToString()) 'Displays 22
Console.WriteLine(ProcessCommand("3-4+6+7+22/3+66*(55)").ToString()) 'Displays 3649.333333333333333333
End Sub
End Module