如何解决C# Roslyn .NET CORE 3.1 CSharpCompilation 动态 RuntimeBinder.Binder.Convert 错误
使用 .NET Core 3.1 (Windows) 我试图动态编译一个使用 dynamic
类型的类。我继续收到错误:
error CS0656: Missing compiler required member 'Microsoft.CSharp.RuntimeBinder.Binder.Convert'
我已经添加了对 Microsoft.CSharp 和 System.Linq.Expressions 的引用,但仍然缺少我无法找到的程序集引用。
我已经浏览了所有可以在 StackOverflow 和 github 上找到的有关此错误的在线参考资料。
一个有趣的提示,这在 .NET Core 5.0 下有效......不幸的是,我还没有准备好升级到 5。
class Program
{
static void Main(string[] args)
{
var code = @"
using System;
using System.Collections.Generic;
namespace Debuggable
{
public class HelloWorld
{
public string DoWork()
{
var a = ""foo"";
var map = new Dictionary<string,object>();
map[""a""] = ""bar"";
if (map.TryGetValue(""a"",out dynamic t))
a = t;
return a;
}
}
}
";
(byte[] a,byte[] b) = CreateAssembly(code);
var assembly = Assembly.Load(a,b);
dynamic instance = assembly.CreateInstance("Debuggable.HelloWorld");
string result = instance.DoWork();
Console.WriteLine(result);
}
public static (byte[],byte[]) CreateAssembly(string code)
{
var encoding = Encoding.UTF8;
var assemblyName = Path.GetRandomFileName();
var symbolsName = Path.ChangeExtension(assemblyName,"pdb");
var references = new MetadataReference[]
{
MetadataReference.CreateFromFile(typeof(object).GetTypeInfo().Assembly.Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.CSharp")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Collections")).Location),MetadataReference.CreateFromFile(typeof(System.Linq.Expressions.ExpressionType).GetTypeInfo().Assembly.Location),};
var SyntaxTrees = new List<SyntaxTree>();
var embeddedTexts = new List<EmbeddedText>();
var sourceCodePath = "generated.cs";
var buffer = encoding.GetBytes(code);
var sourceText = SourceText.From(buffer,buffer.Length,encoding,canBeEmbedded: true);
var SyntaxTree = CSharpSyntaxTree.ParseText(
sourceText,new CSharpParSEOptions().WithLanguageVersion(LanguageVersion.CSharp8),path: sourceCodePath);
var SyntaxRootNode = SyntaxTree.GetRoot() as CSharpSyntaxNode;
var encoded = CSharpSyntaxTree.Create(SyntaxRootNode,null,sourceCodePath,encoding);
SyntaxTrees.Add(encoded);
embeddedTexts.Add(EmbeddedText.FromSource(sourceCodePath,sourceText));
CSharpCompilation compilation = CSharpCompilation.Create(
assemblyName,SyntaxTrees: SyntaxTrees,references: references,options: new CSharpCompilationoptions(OutputKind.DynamicallyLinkedLibrary)
.WithOptimizationLevel(OptimizationLevel.Debug)
.WithPlatform(Platform.Anycpu)
);
using (var assemblyStream = new MemoryStream())
using (var symbolsstream = new MemoryStream())
{
var emitOptions = new EmitOptions(
debuginformationFormat: DebuginformationFormat.PortablePdb,pdbFilePath: symbolsName);
EmitResult result = compilation.Emit(
pestream: assemblyStream,pdbStream: symbolsstream,embeddedTexts: embeddedTexts,options: emitOptions);
if (!result.Success)
{
var errors = new List<string>();
IEnumerable<Diagnostic> failures = result.Diagnostics.Where(diagnostic =>
diagnostic.IsWarningAsError ||
diagnostic.Severity == DiagnosticSeverity.Error);
foreach (Diagnostic diagnostic in failures)
errors.Add($"{diagnostic.Id}: {diagnostic.GetMessage()}");
throw new Exception(string.Join("\n",errors));
}
return (assemblyStream.GetBuffer(),symbolsstream.GetBuffer());
}
}
}
解决方法
我能够使用 MSBuild 添加的引用来缩小范围。如果其他人在使用 .NET Core 3.1 时遇到这种情况,他们会在这里。
MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("Microsoft.CSharp")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("netstandard")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Linq.Expressions")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Private.CoreLib")).Location),MetadataReference.CreateFromFile(Assembly.Load(new AssemblyName("System.Runtime")).Location),
此外,我注意到如果通过显式文件路径加载程序集,所需的引用集是不同的。区别在于 \dotnet\packs
和 \dotnet\shared
程序集。我对此知之甚少,无法说明原因。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。