Roslyn - compiling simple class: “The type or namespace name 'string' could not be found…”

北战南征 提交于 2020-12-13 18:35:23

问题


I'm using the Roslyn API to generate and compile a class. The generated class looks like this:

namespace MyCompany.Product
{
    public class TestClass
    {
        public void Configure(string id)
        {
        }
    }
}

However, when i come to compile it, the Emit(ted) result gives:

error CS0246: The type or namespace name 'string' could not be found (are you missing a using directive or an assembly reference?)

Here is the method which performs the compile:

    private static readonly IEnumerable<string> DefaultNamespaces = new[]
        {
            "System",
            "System.IO",
            "System.Net",
            "System.Linq",
            "System.Text",
            "System.Text.RegularExpressions",
            "System.Collections.Generic"
        };

    public void Compile(IEnumerable<SyntaxTree> syntaxes, string targetPath)
    {

        var assemblyPath = Path.GetDirectoryName(typeof(object).Assembly.Location);
        // assemblyPath = "C:\Windows\Microsoft.NET\Framework64\v4.0.30319"

        IEnumerable<MetadataReference> defaultReferences = new[]
        {
            MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "mscorlib.dll")),
            MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.dll")),
            MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Core.dll")),
            MetadataReference.CreateFromFile(Path.Combine(assemblyPath, "System.Runtime.dll")),

        };
        CSharpCompilationOptions defaultCompilationOptions = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary)
                    .WithOverflowChecks(true).WithOptimizationLevel(OptimizationLevel.Release)
                    .WithUsings(DefaultNamespaces);

        CSharpCompilation compilation = CSharpCompilation.Create(
            targetPath,
            syntaxTrees: syntaxes,
            references: defaultReferences,
            options: defaultCompilationOptions);

        using (var ms = new MemoryStream())
        {
            EmitResult result = compilation.Emit(ms);
            // here, result.Success = false, with it's Diagnostics collection containing the error
            if (!result.Success)
            {
            } 
        }
    }

However, if I compile the below class, but using a constant of type 'string', it compiles as expected, so it doesn't like 'string' when declared as a method parameter type:

namespace MyCompany.Product
{
    public class TestClass
    {
        public const string Id = "e1a64bdc-936d-47d9-aa10-e8634cdd7070";
    }
}

I'm using framework 4.6.1, Microsoft.CodeAnalysis Version=1.3.1.0


回答1:


I fed your first example snippet into CSharpSyntaxTree.ParseText and the result into Compile - it compiled successfully as expected.

My guess is that the node type that you're compiling is somehow wrong. string is a C# keyword that aliases the System.String type and is not a type name per se.

You can use the Roslyn Syntax Visualizer to check for differences between your own SyntaxTree and one generated by CSharpSyntaxTree.ParseText from the expected output.



来源:https://stackoverflow.com/questions/39120241/roslyn-compiling-simple-class-the-type-or-namespace-name-string-could-not

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!