Eval Statement and .Net Runtime Compilation (retry)

by Damiaan Peeters 9. May 2008 11:44

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.


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.


Certified Umbraco Master, Part of Umbraco Certified partner comm-it, .Net and Azure developer, seo lover. Magician in my spare time.

Month List