我正在尝试使用Rosyln将某些代码动态编译到程序集中。我所有的工作都带有一个异常-当我尝试将类型声明为动态时,出现编译错误(来自运行时编译),说:
error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.CSharpArgumentInfo.Create'
Some researchers such as here suggested including a reference to the Microsoft.CSharp.dll
and to the dynamic attribute which I did.
Again, if I switch the type in the code text to int, it works just fine. BTW, this code is based on this great link It requires the Microsoft.CodeAnalysis.Compilers NuGet package. If it matters, I am using a console application with .NET Core 2.2 on Windows.
有什么建议么?
using System;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.Emit;
namespace RoslynTest
{
class Program
{
static void Main(string[] args)
{
var assemblyName = "TestLibrary";
var code = @"
namespace TestNamespace
{
public class TestClass
{
public static int Add(dynamic a, int b) // Works if a is declared as int
{
return a+b;
}
}
}";
SyntaxTree syntaxTree = CSharpSyntaxTree.ParseText(code);
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,
new[] { syntaxTree },
new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).Assembly.Location),
MetadataReference.CreateFromFile(typeof(DynamicAttribute).Assembly.Location),
MetadataReference.CreateFromFile(typeof(Microsoft.CSharp.RuntimeBinder.Binder).Assembly.Location)
},
new CSharpCompilationOptions(OutputKind.DynamicallyLinkedLibrary));
using (var memoryStream = new MemoryStream())
{
EmitResult result = compilation.Emit(memoryStream);
if (result.Success)
{
memoryStream.Seek(0, SeekOrigin.Begin);
Assembly assembly = Assembly.Load(memoryStream.ToArray());
Type testClassType = assembly.GetType("TestNamespace.TestClass");
var addResult = (int)testClassType.GetMethod("Add").Invoke(null, new object[] { 3, 4 });
Console.WriteLine($"Result is {addResult}");
}
else
{
foreach(var error in result.Diagnostics)
Console.WriteLine(error.ToString());
}
Console.ReadLine();
}
}
}
}