Using C# 6 features with CodeDomProvider (Roslyn)

Update: March 2018

Word of caution, NuGet version 1.0.6 … 1.0.8 will
not copy the /roslyn folder to the build output directory on non-web
projects. Best stick with 1.0.5

Run-time compilation using C#6 features requires a new compiler, as @thomas-levesque mentioned. This compiler can be installed by using the nuget package Microsoft.CodeDom.Providers.DotNetCompilerPlatform.

For desktop applications, there’s a problem. The ASP.NET team, in their infinite wisdom have hard-coded the path to the compiler as <runtime-directory>\bin\roslyn\csc.exe See discussion at

If your desktop application is compiled to \myapp\app.exe, the roslyn compiler will be located at \myapp\roslyn\csc.exe, BUT THE CSharpCodeProvider WILL RESOLVE csc.exe as \myapp\bin\roslyn\csc.exe

As far as I can tell, you have two options

  1. Create a post-build and/or installation routine that will move the \roslyn subdirectory to \bin\roslyn.
  2. Fix the runtime code through reflection black magic.

Here is #2, by exposing the CSharpCodeProvider as a property in a utility class.

using System.Reflection;
using Microsoft.CodeDom.Providers.DotNetCompilerPlatform;

static Lazy<CSharpCodeProvider> CodeProvider { get; } = new Lazy<CSharpCodeProvider>(() => {
    var csc = new CSharpCodeProvider();
    var settings = csc
        .GetField("_compilerSettings", BindingFlags.Instance | BindingFlags.NonPublic)

    var path = settings
        .GetField("_compilerFullPath", BindingFlags.Instance | BindingFlags.NonPublic);

    path.SetValue(settings, ((string)path.GetValue(settings)).Replace(@"bin\roslyn\", @"roslyn\"));

    return csc;

Leave a Comment