C# Roslyn .NET CORE 3.1 CSharpCompilation 动态 RuntimeBinder.Binder.Convert 错误

如何解决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 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?