Compiling code at runtime is incredibly easy thanks to the CSharpCodeProvider class. But as always, there is a catch. Let's say you have the following code snippet somewhere in your shiny new VC# 2008 project:

CSharpCodeProvider codeProvider = new CSharpCodeProvider();

CompilerResults results = codeProvider.CompileAssemblyFromSource(new CompilerParameters(), @"

    public class Foo

    {

        public int MyProperty { get; set; }

    }

 

    public static class Bar

    {

        private static Foo myFooValue = new Foo { MyProperty = 42 };

 

        public static Foo MyFoo { get { return myFooValue; } }

    }");

 

foreach (String msg in results.Output)

    Debug.WriteLine(msg);

 

PropertyInfo myPropertyPi = results.CompiledAssembly.GetType("Foo").GetProperty("MyProperty");

PropertyInfo myFooPi      = results.CompiledAssembly.GetType("Bar").GetProperty("MyFoo");

 

Object PropertyValue = myPropertyPi.GetValue(myFooPi.GetValue(null, null), null);

Debug.WriteLine("Value of Bar.MyFoo.MyProperty: " + PropertyValue.ToString());

Now, the code passed to CompileAssemblyFromSource() doesn't do anything useful but it uses auto-implemented properties and object initializers which are both C# 3.0 features. While this code seems to look good it will crash with a FileNotFoundException with the message "Could not load file or assembly 'file:///C:\Users\[username]\AppData\Local\Temp\[tempfilename].dll' or one of its dependencies. The system cannot find the file specified." as soon as it tries to read the CompiledAssembly property. Assuming you built a debug version the debug output will reveal why:

Microsoft (R) Visual C# 2005 Compiler version 8.00.50727.1434

for Microsoft (R) Windows (R) 2005 Framework version 2.0.50727

Copyright (C) Microsoft Corporation 2001-2005. All rights reserved.

 

c:\Users\[username]\AppData\Local\Temp\[tempfilename].0.cs(9,61): error CS1526: A new expression requires () or [] after type

The first line is the interesting one. Despite the fact that a new project in VC# 2008 targets the .NET Framework 3.5 by default the CSharpCodeProvider is invoking version 8.0 of the C# compiler which first shipped with the .NET Framework 2.0 and of course doesn’t know anything about the latest C# language features. Now, there are several websites suggesting using a different CSharpCodeProvider constructor with the following input:

CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "3.5" } });

 

The only problem is that it will not work. We've trade the FileNotFoundException for an InvalidOperationException with the dreaded message "Compiler executable file csc.exe cannot be found." which will be thrown by CompileAssemblyFromSource(). Fortunately, there is literally only one little character between us and success:

 

CSharpCodeProvider codeProvider = new CSharpCodeProvider(new Dictionary<String, String> { { "CompilerVersion", "v3.5" } });

 


This posting is provided "AS IS" with no warranties, and confers no rights.