问题
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