Click here to Skip to main content
Licence CPOL
First Posted 12 Oct 2005
Views 149,066
Downloads 1,327
Bookmarked 98 times

Evaluate C# Code (Eval Function)

By | 12 Oct 2005 | Article
An example that provides an Eval function for compiling/evaluating C# code at runtime.

Sample Image - EvalCSCode.jpg

Introduction

This example shows an "Eval" function for C# and implements different usages of this evaluate function. The library is written in C# and can be tested with the MainForm in the solution.

Source view

Here you will see all the trick. The code generates a class structure with a basic "function prototype" in which the code to evaluate is filled in. The execution of the function should execute your code:

// Eval > Evaluates C# sourcelanguage
public static object Eval(string sCSCode) {

  CSharpCodeProvider c = new CSharpCodeProvider();
  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.ReferencedAssemblies.Add("system.windows.forms.dll");
  cp.ReferencedAssemblies.Add("system.drawing.dll");

  cp.CompilerOptions = "/t:library";
  cp.GenerateInMemory = true;

  StringBuilder sb = new StringBuilder("");
  sb.Append("using System;\n" );
  sb.Append("using System.Xml;\n");
  sb.Append("using System.Data;\n");
  sb.Append("using System.Data.SqlClient;\n");
  sb.Append("using System.Windows.Forms;\n");
  sb.Append("using System.Drawing;\n");

  sb.Append("namespace CSCodeEvaler{ \n");
  sb.Append("public class CSCodeEvaler{ \n");
  sb.Append("public object EvalCode(){\n");
  sb.Append("return "+sCSCode+"; \n");
  sb.Append("} \n");
  sb.Append("} \n");
  sb.Append("}\n");

  CompilerResults cr = icc.CompileAssemblyFromSource(cp, sb.ToString());
  if( cr.Errors.Count > 0 ){
      MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText, 
         "Error evaluating cs code", MessageBoxButtons.OK, 
         MessageBoxIcon.Error );
      return null;
  }

  System.Reflection.Assembly a = cr.CompiledAssembly;
  object o = a.CreateInstance("CSCodeEvaler.CSCodeEvaler");

  Type t = o.GetType();
  MethodInfo mi = t.GetMethod("EvalCode");

  object s = mi.Invoke(o, null);
  return s;

}

Thanks fly out to:

Credits:

  • Kim Hauser (dave) - Application Developer & System Engineer.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

kim.david.hauser

Software Developer (Senior)

Switzerland Switzerland

Member



Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
You must Sign In to use this message board. (secure sign-in)
 
Search this forum  
 FAQ
    Noise  Layout  Per page   
  Refresh
QuestionHow do you replace a string at a given position with it's working code representative? PinmemberLarissa Schön0:47 17 Mar '12  
GeneralAwesome, though quick question Pinmembermbainrot21:03 10 Apr '09  
QuestionEvalToObject Question Pinmembergravelkm2:43 14 Nov '08  
Questioncan a web project use "ReferencedAssemblies.Add("customer.dll")" Pinmemberwlbkeats23:34 7 Dec '06  
GeneralUses of Eval PinmemberAnup Shinde16:06 29 Sep '06  
GeneralTotal waste of time... Pinmembermarkman@shaw.ca12:08 3 Mar '06  
GeneralRe: Total waste of time... PinmemberPascal Ganaye9:12 20 Mar '06  
GeneralRe: Total waste of time... PinPopularmembermarkman@shaw.ca5:54 21 Mar '06  
GeneralRe: Total waste of time... PinmemberGraham Harrison23:34 11 Jan '07  
GeneralAn Eval Function for C# using JScript.NET (JavaScript) PinmemberMichael Freidgeim0:48 5 Jan '11  
GeneralRe: Total waste of time... Pinmemberkim.hauser2:37 8 Feb '07  
GeneralRe: Total waste of time... Pinmembermarketware11:25 30 Aug '07  
GeneralRe: Total waste of time... Pinmembermarketware11:08 31 Aug '07  
GeneralI dont think Total waste of time.. PinmemberMidax9:40 27 Apr '10  
QuestionUses PinmemberEvilToilet9:15 23 Oct '05  
AnswerRe: Uses Pinmemberkim.hauser11:03 2 Nov '05  
GeneralThanks for review... Pinmemberkim.hauser10:13 21 Oct '05  
QuestionUsing a static method instead Pinmemberanonymous20:07 19 Oct '05  
AnswerRe: Using a static method instead Pinmemberaprenot10:17 21 Oct '05  
GeneralRe: Using a static method instead PinmemberToli Cuturicu11:22 20 Dec '10  
GeneralExcellent! But Pinmembercccccbbbbb14:41 19 Oct '05  
GeneralRe: Excellent! But Pinmemberkim.hauser0:29 22 Oct '05  
AnswerRe: Excellent! But PinmemberKevan Davis11:18 1 Dec '06  
Used this is a project I'm working on. It's a slight modification of what you posted.
I also tried to figure out the AppDomain, this is where I got when I ran into a brick wall.
In order to load the code into the new AppDomain, you will need 2 classes, the first class creates the AppDomain, and loads the 2nd class into it, similar to what I have at the bottom. The second class will inherit MarshalByRefObject and will do all the dynamic compilation.
When/if I get around to finishing this, I'll post it as well.
 

using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using Microsoft.CSharp;
 
namespace Test
{
///
/// C# Code Evaluator
/// Based on work by Kim Hauser found at http://www.codeproject.com/csharp/evalcscode.asp
///

class CSEvaluator
{
///
/// Assemblies are what follow "using"
///

public List Assemblies;
///
/// References are in the Solution Explorer in the References folder
///

public List References;
///
/// Namespace to evaluate in, in case you want to be able to access external classes
///

public string Namespace;
 
public CSEvaluator()
{
References = new List();
// Adding default References
References.Add("System");
References.Add("System.Drawing");
References.Add("System.Windows.Forms");
References.Add("System.Xml");
 
Assemblies = new List();
// Adding default assemblies
Assemblies.Add("System");
Assemblies.Add("System.Drawing");
Assemblies.Add("System.Drawing.Drawing2D"); // notice that Drawing2D is not in the list of references
Assemblies.Add("System.Windows.Forms"); // this is because System.Drawing is the reference for it
Assemblies.Add("System.Xml");
 
Namespace = this.GetType().Namespace.ToString();
}
 
///
/// Evaluates C# Code
///

/// The Code to evaluate
/// parameter string, i.e. "string sCSCode, string sParms, object[] oParms"
/// array of parameter objects
///
public object Eval(string sCSCode, string sParms, object[] oParms)
{
CompilerParameters cp = new CompilerParameters();
 
// load references
foreach (string r in References)
cp.ReferencedAssemblies.Add(r + ".dll");
 
cp.CompilerOptions = "/t:library";
cp.GenerateInMemory = true;
 
StringBuilder sb = new StringBuilder("");
// load assemblies
foreach (string s in Assemblies)
sb.Append("using " + s + ";\n");
 
sb.Append("\nnamespace " + Namespace + "\n{\n");
sb.Append("\tpublic class temp_Eval\n\t{\n");
sb.Append("\t\tpublic object Eval(" + sParms + ")\n\t\t{\n");
sb.Append("\t\t\treturn " + sCSCode + "; \n");
sb.Append("\t\t}\n");
sb.Append("\t}\n");
sb.Append("}\n");
 
CompilerResults cr = CodeDomProvider.CreateProvider("CSharp").CompileAssemblyFromSource(cp, sb.ToString());
if (cr.Errors.Count > 0)
{
MessageBox.Show("ERROR: " + cr.Errors[0].ErrorText,
"Error evaluating cs code", MessageBoxButtons.OK,
MessageBoxIcon.Error);
return null;
}
 
// *** Below this point is a work in progress, watch out for falling debris ***
 
//AppDomain evalDomain = AppDomain.CreateDomain("evalDomain");
System.Reflection.Assembly a = cr.CompiledAssembly;
//evalDomain.DefineDynamicAssembly(a.GetName(), System.Reflection.Emit.AssemblyBuilderAccess.Run); // problem here can be solved with MarshalByRefObject
//object o = evalDomain.CreateInstance(a.GetName().ToString(), Namespace + ".temp_Eval"); // it probably won't work like this
object o = a.CreateInstance(Namespace + ".temp_Eval");
 
Type t = o.GetType();
System.Reflection.MethodInfo mi = t.GetMethod("Eval");
 
object ec = mi.Invoke(o, oParms);
 
//AppDomain.Unload(evalDomain);
return ec;
}
}
}

GeneralExcellent !! PinmemberTittle Joseph19:46 18 Oct '05  
GeneralThanks, but ... PinmemberHerman Chelette2:33 18 Oct '05  

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

Permalink | Advertise | Privacy | Mobile
Web02 | 2.5.120529.1 | Last Updated 13 Oct 2005
Article Copyright 2005 by kim.david.hauser
Everything else Copyright © CodeProject, 1999-2012
Terms of Use
Layout: fixed | fluid