无法从源代码在 Roslyn 中创建编译

And*_*dry 4 .net c# reflection roslyn roslyn-code-analysis

出于测试目的,我需要从包含源代码的System.Reflection.Assembly字符串中获取 a 。source我正在使用罗斯林:

SyntaxTree tree = CSharpSyntaxTree.ParseText(source);
CSharpCompilation compilation = CSharpCompilation.Create("TestCompilation", new[] { tree });

Assembly assembly = null;
using (var stream = new MemoryStream())
{
    var emitResult = compilation.Emit(stream);
    if (!emitResult.Success)
    {
        var message = emitResult.Diagnostics.Select(d => d.ToString())
            .Aggregate((d1, d2) => $"{d1}{Environment.NewLine}{d2}");

        throw new InvalidOperationException($"Errors!{Environment.NewLine}{message}");
    }

    stream.Seek(0, SeekOrigin.Begin);
    assembly = Assembly.Load(stream.ToArray());
}
Run Code Online (Sandbox Code Playgroud)

正如你所看到的,我在这里的尝试是发出一个CSHarpCompilation对象,以便我可以获得Assembly稍后的对象。我正在尝试这样做:

var source = @"
  namespace Root.MyNamespace1 {
    public class MyClass {
    }
  }
";
Run Code Online (Sandbox Code Playgroud)

发出错误

但我失败var emitResult = compilation.Emit(stream)并输入显示错误的条件。我收到 1 个警告和 3 个错误:

  • 警告 CS8021:未找到 RuntimeMetadataVersion 值。找不到包含 System.Object 的程序集,也没有通过选项指定 RuntimeMetadataVersion 的值。
  • (3,34):错误CS0518:未定义或导入预定义类型“System.Object”
  • (3,34):错误CS1729:“对象”不包含采用0个参数的构造函数
  • 错误 CS5001:程序不包含适合入口点的静态“Main”方法

所以看来我需要添加引用mscorelib,而且我似乎还需要告诉 Roslyn 我想发出一个类库,而不是一个可执行程序集。怎么做?

Jos*_*rty 7

You're missing a metadata reference to mscorlib and you can change the compilation options via CSharpCompilationOptions.

Create your compilation as follows:

var Mscorlib = MetadataReference.CreateFromFile(typeof(object).Assembly.Location);
var options = new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary);
var compilation = CSharpCompilation.Create("TestCompilation",
    syntaxTrees: new[] { tree }, references: new[] { Mscorlib }, options: options);
Run Code Online (Sandbox Code Playgroud)