Yes I come from a VBA environment. Microsoft Access all the way. Last years I am into .Net but I was still missing my "good old" Eval statement. A colleague triggered my curiosity and I started digging for a solution.
We dive into 2 methods. The first is using the Microsoft Script Control, the second is the Runtime Compilation.
[more]
The easiest solution is probably to take the "Good Old" eval method from where it is available. This means that you will need to set a reference to: COM Microsoft Script Control 1.0.
MSScriptControl.ScriptControlClass mScriptControl; mScriptControl = new MSScriptControl.ScriptControlClass(); mScriptControl.Language = "VBScript"; mScriptControl.AllowUI = false; mScriptControl.Reset(); try { retval = mScriptControl.Eval(s); } catch{ /* ... */ }
You have to admit, this isn't to difficult.
This is well described on vb-tips.com.
Another solution would be Compilation at Runtime.
The simplest example I found was at EggheadCafe: Build a Custom .NET "EVAL" Provider. It is created for VB, but can easily be changed to C#.
For archiving purposes, here is the code...
VBCodeProvider c = new VBCodeProvider();ICodeCompiler icc = c.CreateCompiler();CompilerParameters cp = new CompilerParameters();cp.ReferencedAssemblies.Add("system.dll");cp.ReferencedAssemblies.Add("system.xml.dll");cp.ReferencedAssemblies.Add("system.data.dll");cp.CompilerOptions = "/t:library";cp.GenerateInMemory = true;StringBuilder sb = new StringBuilder("");Debug.WriteLine(sb.ToString());// look at this to debug your eval stringCompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());System.Reflection.Assembly a = cr.CompiledAssembly;object o;MethodInfo mi;o = a.CreateInstance("PAB.PABLib");Type t = o.GetType();mi = t.GetMethod("EvalCode");object s;s = mi.Invoke(o, null);return s;
To compile some c# code at runtime I found the Runtime Compilation (A .NET eval statement) article on CodeProject. This is a library which cuts out the compiler references etc. If you use this 'Evaluator' class, you can call a e.g. a StringChanger method as described below. This code is also available on the mentioned page as example.
string myCode = "s =+ \" TEST\"; return s";
MethodResults stringChanger = null;StringBuilder source = new StringBuilder();source.Append("public string StringChanger(string s)");source.Append(Environment.NewLine);source.Append("{");source.Append(Environment.NewLine);source.Append(myCode);source.Append(Environment.NewLine);source.Append("}");try{ stringChanger = Eval.CreateVirtualMethod( new CSharpCodeProvider().CreateCompiler(), source.ToString(), "StringChanger", new CSharpLanguage(), false);}catch(CompilationException ce){ MessageBox.Show(this, "Compilation Errors: " + Environment.NewLine + ce.ToString()); return;}try{ output.Text = (string)stringChanger.Invoke(inputString.Text);}catch(System.Reflection.TargetInvocationException tie){ MessageBox.Show(this, "Method-Thrown Exception: " + Environment.NewLine + tie.InnerException.ToString()); return;}
We learned today that there are many possibilities with the System.Reflection and the System.CodeDom.Compiler namespaces.