views:

650

answers:

2

I have the following, fairly standard code as a wrapper around CSharpCodeProvider. This class works very well, and performs just fine, etc, etc. But, despite the fact that my application is built against .NET 3.5 and is referencing v3.5 assemblies when doing this compilation, I still don't get access to any of the extra nice C# 3.5 syntax like lambda's or auto-properties. Is there some way to get this working?

I was under the impression that this class just wrapped around csc.exe, an idea that would seem to be confirmed by my firewall (my application tries to access csc.exe). Perhaps I just need to set options.CompilerOptions to something?

protected virtual void Compile()
{
    Microsoft.CSharp.CSharpCodeProvider csProvider = new Microsoft.CSharp.CSharpCodeProvider();

    CompilerParameters options = new CompilerParameters();
    options.GenerateExecutable = false;
    options.GenerateInMemory = true;
    options.IncludeDebugInformation = true;

    foreach (string s in this.ReferencedAssemblies)
    {
        options.ReferencedAssemblies.Add(s);
    }

    CompilerResults result;
    string source = this.CodeTemplate;

    // [snip] Do some manipulation to fill in the template with values.

    result = csProvider.CompileAssemblyFromSource(options, source);

    this.HasErrors = result.Errors.HasErrors;
    this.Errors = new CompilerError[result.Errors.Count];
    result.Errors.CopyTo(Errors, 0);

    if (HasErrors && ThrowOnErrors)
        throw new InvalidProgramException("The code currently stored in the " + this.GetType() + " cannot be compiled.");
    else if (HasErrors)
        return;
    this.CompiledAssembly = result.CompiledAssembly;
}

EDIT:

I have references to mscorlib, System.Core, System.Text and one of my own assemblies at the moment.

A: 

In referenced assemblies, try adding a reference to System.Core. That should do it. A lot of 3.5 functionality is in there. If that doesn't do it, open build properties for your current project and check what other assemblies you may have to load.

David Hedlund
See my edit, but would references really make a difference to compiler behaviour?
Matthew Scharley
No, they wouldn't. You want C# 3.0 language features, not (necessarily) the .NET framework 3.5 class library. One does not require the other.
Lucas
+11  A: 

There's a compiler flag that you can pass into the constructor (in a dictionary):

Dictionary<string,string> options = new Dictionary<string,string>
{ 
    { "CompilerVersion", "v3.5" }
};

var compiler = new CSharpCodeProvider(options);

That's what's worked for me, anyway...

Jon Skeet
+1: I wrote a simple wrapper for this with enum values for framework versions so that I can specify which parts of the app support which compiler.
Jeff Yates