Search code examples
c#codedomvaluetuple

Using ValueTuple while compiling a class from text runtime


I'm trying to compile a class from text at runtime. My problem is that my class uses a valueTupe in a function (AllLines), and I receive an error "C:\xxxx.cs(19,28): error CS0570: 'BaseClass.AllLines' is not supported by the language" when using this code

CodeDomProvider objCodeCompiler = new Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider();

CompilerParameters objCompilerParameters = new CompilerParameters();

objCompilerParameters.ReferencedAssemblies.Add("mscorlib.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.IO.dll");
objCompilerParameters.ReferencedAssemblies.Add("System.Linq.dll");
CompilerResults objCompileResults = objCodeCompiler.CompileAssemblyFromFile(objCompilerParameters, filename);

EDIT:

The Textfile looks as follows :

using System;
using System.Collections.Generic;
using System.Linq;
namespace MyNamespace
{
    public abstract class BaseClass
    {
        public List<(int LineNumber, string Value)> AllLines
        {
            ...
        }
    }
}

I'm using Microsoft.CodeDom.Providers.DotNetCompilerPlatform v2.0.0.0, Microsoft (R) Visual C# Compiler version 1.0.0.50618

Unsure if that is the actual version of roslyn.


Solution

  • Firstly, you were correct that you were using Roslyn as you are using Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider from the NuGet package Microsoft.CodeDom.Providers.DotNetCompilerPlatform.

    However, the issue you are facing is that your text file does not contain valid C#.

    1. Your declaration of List<T> is invalid in enclosing the type parameters in parentheses
    2. You are adding names(?) to the type parameter declaration (LineNumber, Value).
    3. You're providing two type parameters when List<T> only accepts one. (Maybe you meant to use a Dictionary<TKey, TValue>)
    4. There is no body to your property declaration

    Try replacing your text file with:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    namespace MyNamespace
    {
        public abstract class BaseClass
        {
            public Dictionary<int, string> AllLines
            {
                get; set;
            }
        }
    }
    

    Note, you don't actually need using System or using System.Linq for this example. Also note, you don't need to use Roslyn for this. The old fashioned CodeDOM can compile it (replace Microsoft.CodeDom.Providers.DotNetCompilerPlatform.CSharpCodeProvider with Microsoft.CSharp.CSharpCodeProvider).