Click here to Skip to main content
13,597,163 members
Click here to Skip to main content
Add your own
alternative version


44 bookmarked
Posted 14 Jun 2004

Generating code from code

, 14 Jun 2004
Rate this:
Please Sign up or sign in to vote.
This article describes how to programmatically generate and run .NET code.


Some days ago, I read the good CodeProject article "Compiling with CodeDom" by Gustavo Bonansea, where he shows how to use .NET classes from the CodeDom namespace, to compile .NET code programmatically (and, of course, without using the command-line!). As rightly mentioned in the final comments of that article, .NET allows you not only to programmatically compile code, but also to programmatically generate code. In the following paragraphs, I will show a simple example of code generation.


Imagine to have to implement an arithmetic expression interpreter, that is a piece of code capable to take an expression as an input string and to compute the result of that expression. The classic approach to this problem is to write a parser that recognizes each token of the input expression (numbers, operators, parenthesis and so on), builds an expression tree representing the expression structure, and then walks that tree to compute the result.

Another approach consists in generating a function that actually computes that expression. If you think about an expression like:

1 + 2 * 3 - 4 / 5

it would be perfect to compute the result simply invoking a function like:

Public Shared Function MyMethod() As Single
   Return 1 + 2 * 3 - 4 / 5
End Function

Well, the code of this sample actually does that, in these steps:

  • it creates the function (as a shared method of the class MyClass in the namespace MyNamespace) through .NET CodeDom;
  • it compiles the generated code in an assembly;
  • it loads the newly-created assembly and dynamically invokes MyMethod.

The Code

Here is the code of a console application that demonstrates the dynamic code generation and execution for the "arithmetic expression interpreter" depicted above.

Imports System
Imports System.Collections
Imports System.CodeDom
Imports System.CodeDom.Compiler
Imports System.IO
Imports System.Reflection
Imports Microsoft.CSharp
Imports Microsoft.VisualBasic

Public Class ParseExpr

  Public Shared Sub Main()
    Console.WriteLine("Expression evaluation demo")
    Console.WriteLine("Type an arithmetic expression: ")
    Dim Expression As String = Console.ReadLine()

    Console.WriteLine("Your expression is evaluated as: ")
  End Sub

  Private Shared Function ProcessExpression(ByVal _
                     Expression As String) As Single
    Dim VBcp As New VBCodeProvider()
    Dim cg As ICodeGenerator = VBcp.CreateGenerator()
    Dim AssemblySourceFile As String = "MyClass.vb"
    Dim AssemblyFile As String = "MyClass.dll"

    ' Generating the assembly source file
    Dim tw As TextWriter
    tw = New StreamWriter(New _
            FileStream(AssemblySourceFile, FileMode.Create))
    GenerateEvalMethod(tw, Expression, cg)

    ' Compiling the source file to an assembly DLL (IL code)
    Dim cc As ICodeCompiler = VBcp.CreateCompiler()
    Dim cpar As New CompilerParameters()
    cpar.OutputAssembly = AssemblyFile
    cpar.GenerateExecutable = False     ' result is a .DLL
    cpar.GenerateInMemory = False
    Dim compRes As CompilerResults
    compRes = cc.CompileAssemblyFromFile(cpar, AssemblySourceFile)

    ' Invoking a method of the newly-created assembly
    Dim ass As [Assembly]
    ass = compRes.CompiledAssembly
    Dim ty As Type = ass.GetType("MyNamespace.MyClass")
    Dim mi As MethodInfo = ty.GetMethod("MyMethod")
    Dim Result As Single = CType(mi.Invoke(Nothing, Nothing), Single)
    Return Result
  End Function

  Private Shared Sub GenerateEvalMethod(ByVal tw As _
      TextWriter, ByVal Expression As String, _
      ByVal CodeGen As ICodeGenerator)

    '> Namespace MyNamespace
    Dim ns As New CodeNamespace("MyNamespace")

    '> Public Class MyClass
    Dim ty As New CodeTypeDeclaration("MyClass")
    ty.IsClass = True
    ty.TypeAttributes = TypeAttributes.Public

    Dim mm As New CodeMemberMethod()

    '> ' Expression:...
    mm.Comments.Add(New _
      CodeCommentStatement([String].Format("Expression:{0}", _

    '> Public Shared Function MyMethod() As Single
    mm.Name = "MyMethod"
    mm.ReturnType = New CodeTypeReference("System.Single")
    mm.Attributes = MemberAttributes.Public Or MemberAttributes.Static

    '> Return ...
    mm.Statements.Add(New _
      CodeMethodReturnStatement(New CodeSnippetExpression(Expression)))

    CodeGen.GenerateCodeFromNamespace(ns, tw, Nothing)
  End Sub

End Class

Some notes

  1. Because the input expression is computed as a part of the application code, you can insert in it any valid function. For example:
    System.Math.Pow(5,2) * System.Math.PI

    will correctly compute the area of a circle with radius = 5. This works because the System.dll is already referred with:


    If you want to support in your expressions other functions as well (also from custom assemblies), just remember to add an item to the ReferencedAssemblies collection.

  2. It has been noted (by mav.northwind - thanks!) that there is no need to actually generate the physical assembly file MyClass.dll, because you can instruct the compiler to generate the assembly in memory. To do this, modify the code so:
    'cpar.OutputAssembly = AssemblyFile    ' remove this line
    cpar.GenerateInMemory = True           ' set this option to True
  3. We can also avoid the physical generation of the MyClass.vb source file, with few modifications to our code. You only need to comment out these lines:
    tw = New StreamWriter(New FileStream(AssemblySourceFile, FileMode.Create))
    GenerateEvalMethod(tw, Expression, cg)
    compRes = cc.CompileAssemblyFromFile(cpar, AssemblySourceFile)

    substituting them with:

    Dim sb As New System.Text.StringBuilder()
    tw = New StringWriter(sb)
    GenerateEvalMethod(tw, Expression, cg)
    compRes = cc.CompileAssemblyFromSource(cpar, sb.ToString())


Of course, dynamically generating, compiling, and running code in this way is not a good solution when you need maximum performance. But you will agree with me that the flexibility of this approach could be decisive in a lot of situations.


This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


About the Author

Alberto Venditti
Technical Lead
Italy Italy
I was born in 1970.

My first computer experience dates back to early 80s, with a Sinclair ZX81.
From that time on, as many "friends" say, my IT-illness has increased year by year.

I graduated in Electronic Engineering and earned the following Microsoft certifications:
MCP, MCT, MCDBA, MCSD, MCAD, MCSD for .NET (early achiever).

I worked in IT as a developer, a teacher, a consultant, a technical writer, a technical leader.
IT knowledge applied to real life is my primary interest and focus.

You may also be interested in...


Comments and Discussions

QuestionGenerate the Assembly at runtime Pin
NPotti4-Mar-10 2:09
memberNPotti4-Mar-10 2:09 
AnswerRe: Generate the Assembly at runtime Pin
Alberto Venditti8-Mar-10 0:00
memberAlberto Venditti8-Mar-10 0:00 
GeneralGreat Job! Pin
Shane Story4-Feb-09 9:33
memberShane Story4-Feb-09 9:33 
GeneralRe: Great Job! Pin
Alberto Venditti4-Feb-09 21:27
memberAlberto Venditti4-Feb-09 21:27 
GeneralVB.Net Dll generator Pin
Member 47743574-Dec-07 12:02
memberMember 47743574-Dec-07 12:02 
QuestionExecutable Generating App Pin
noodleguy16-Sep-07 7:54
membernoodleguy16-Sep-07 7:54 
AnswerRe: Executable Generating App Pin
Alberto Venditti16-Sep-07 21:53
memberAlberto Venditti16-Sep-07 21:53 
AnswerRe: Executable Generating App Pin
Shane Story4-Feb-09 9:30
memberShane Story4-Feb-09 9:30 
QuestionA quick question Pin
Alex Douma14-Apr-07 7:19
memberAlex Douma14-Apr-07 7:19 
AnswerRe: A quick question Pin
Alberto Venditti15-Apr-07 11:28
memberAlberto Venditti15-Apr-07 11:28 
Questioncan a web project use "ReferencedAssemblies.Add("customer.dll")" [modified] Pin
wlbkeats7-Dec-06 23:35
memberwlbkeats7-Dec-06 23:35 
AnswerRe: can a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
Alberto Venditti8-Dec-06 0:05
memberAlberto Venditti8-Dec-06 0:05 
GeneralRe: can a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
wlbkeats8-Dec-06 0:15
memberwlbkeats8-Dec-06 0:15 
GeneralRe: can a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
Alberto Venditti9-Dec-06 8:49
memberAlberto Venditti9-Dec-06 8:49 
GeneralRe: can a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
wlbkeats10-Dec-06 14:00
memberwlbkeats10-Dec-06 14:00 
GeneralRe: can a web project use "ReferencedAssemblies.Add("customer.dll")" Pin
Alberto Venditti10-Dec-06 23:00
memberAlberto Venditti10-Dec-06 23:00 
QuestionWould it possible to add the parameter variebles ? Pin
Kent Liu31-Oct-06 22:19
memberKent Liu31-Oct-06 22:19 
AnswerRe: Would it possible to add the parameter variebles ? Pin
Alberto Venditti2-Nov-06 21:39
memberAlberto Venditti2-Nov-06 21:39 
QuestionCan this be done in memory? Pin
Hans.Baumann23-Jun-05 0:32
memberHans.Baumann23-Jun-05 0:32 
AnswerRe: Can this be done in memory? Pin
Alberto Venditti11-Jul-05 12:23
memberAlberto Venditti11-Jul-05 12:23 
GeneralSome remarks Pin
mav.northwind15-Jun-04 20:52
membermav.northwind15-Jun-04 20:52 
GeneralRe: Some remarks Pin
Alberto Venditti15-Jun-04 21:38
memberAlberto Venditti15-Jun-04 21:38 
GeneralRe: Some remarks Pin
mav.northwind15-Jun-04 21:52
membermav.northwind15-Jun-04 21:52 
GeneralRe: Some remarks Pin
Alberto Venditti15-Jun-04 23:21
memberAlberto Venditti15-Jun-04 23:21 
GeneralRe: Some remarks Pin
mav.northwind16-Jun-04 0:33
membermav.northwind16-Jun-04 0:33 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    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 | Cookies | Terms of Use | Mobile
Web03-2016 | 2.8.180621.3 | Last Updated 15 Jun 2004
Article Copyright 2004 by Alberto Venditti
Everything else Copyright © CodeProject, 1999-2018
Layout: fixed | fluid