【问题标题】:Can't load System.ValueTuple in dynamically compiled code无法在动态编译的代码中加载 System.ValueTuple
【发布时间】:2021-02-24 14:19:36
【问题描述】:

我想在 .net 4.6.1 上的动态编译代码中使用元组。 下面是一个最小的测试用例。任何帮助,将不胜感激。谢谢!

// First, install System.ValueTuple 4.5 package via nuget into test Project.
using System;
using System.CodeDom.Compiler;

public class Program
{
    public static void Main()
    {
        string source = @"
using System;
namespace TupleTest {
    class TupleTest {
        public void test(){
            (int key, string value) tuple1 = (1, ""ok"");
        }
    }
}";
        var cp = new CompilerParameters();
        cp.GenerateExecutable = false;
        cp.GenerateInMemory = true;
        cp.IncludeDebugInformation = false;
        // cp.IncludeDebugInformation = true;
        cp.WarningLevel = 1;
        cp.TreatWarningsAsErrors = true;
        cp.ReferencedAssemblies.Add("System.dll");
        cp.ReferencedAssemblies.Add("System.ValueTuple.dll");
        var compiler = Microsoft.CSharp.CSharpCodeProvider.CreateProvider("CSharp");
        var compilerResults = compiler.CompileAssemblyFromSource(cp, source);

        if (compilerResults.Errors.HasErrors)
        {
            Console.WriteLine("Compile Failed: ");
            foreach (var error in compilerResults.Errors)
                Console.WriteLine("Line {0}, Column {1}: error {2}: {3}",
                                  error.Line, error.Column, error.ErrorNumber, error.ErrorText);
        }
        else
        {
            Console.WriteLine("Compile Pass");
        }
    }
}

在这上面浪费了一天,还是打不通。

总是同样的错误,它根本无法识别元组。

顺便说一句,出于明显的安全原因,测试代码无法在在线 codefiddling 中进行测试,需要本地环境。验证。

Line 6, column 37: error CS1003: Syntax error, '=>' expected
Line 6, column 47: error CS1026: ) expected
Line 6, column 47: error CS1525: Invalid expression term ','
Line 6, column 49: error CS1002: ; expected
Line 6, column 53: error CS1002: ; expected
Line 6, column 53: error CS1525: Invalid expression term ')'

还尝试替换cp.ReferencedAssemblies.Add("System.ValueTuple.dll");cp.ReferencedAssemblies.Add("C:\\nugetpkg\\System.ValueTuple.dll"); , 徒劳无功。 还要加倍加给

Line 0, column 0: error CS1703: 
An assembly with the same identity 'System.ValueTuple, Version=4.0.3.0, 
Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51' 
has already been imported. Try removing one of the duplicate references.

感谢您的帮助。使用答案中提到的基于 roslyn 的编译器解决。 PS:所有对System.ValueTuple 的引用都需要从CompilerParameter.ReferencedAssemblies 中删除,以避免多重引用错误。

【问题讨论】:

  • ValueTuple 仅在 .NET Framework 4.7 中可用...
  • @Codexer,不,它是通过 NuGet 安装的。谢谢,忘记注意了。
  • 好的,是的,安装 NuGet 是不同的。
  • 这不是关于库或类型,而是关于编译器。编译器不理解您使用的语法,您无法安装 nuget 包来解决此问题,您必须使用更新的编译器版本。

标签: c# tuples assembly-references dynamic-compilation valuetuple


【解决方案1】:

您正在使用来自 C# 的 later version 的语言功能。如果你这样做:

        string source = @"
using System;
namespace TupleTest {
    class TupleTest {
        public void test(){
            var tuple1 = ValueTuple.Create(1, ""ok"");
            Console.WriteLine(tuple1.Item2);
        }
    }
}";

然后编译就好了。

我很确定 CSharpCodeProvider 仅适用于 C# 语言的版本 5 或 6。也许this answer 会帮助你升级到版本 7。

查看this chart,了解框架版本与语言版本之间的关系。

【讨论】:

  • 我正在开发一个类库,主程序的目标是 4.6.1。我想使用 NuGet 包 System.ValueTuple 来启用元组。因此,我必须坚持使用 4.6 一段时间...
  • @Ben -- 这与您正在执行的项目的框架没有任何关系。这与您使用的 C# 语言的版本有关。它们是完全不相关的东西。
  • @Andy 代码提供者使用的版本必须是 ISO-1、ISO-2、3、4、5 或默认
  • 这与 nuget 包无关,您通过 CSharpCodeProvider 使用的编译器不理解语法。如果无法将 CSharpCodeProvider 配置为使用较新的编译器,则您根本无法执行此操作。 nuget 包无法向编译器添加语法。
  • @LasseV.Karlsen,谢谢。我想我现在明白你们的意思了。语言规范版本(源文本)=> 编译器版本 ==targets==> assmbely implimentations 版本。事实上,我需要一个新的编译器。
猜你喜欢
  • 2011-09-03
  • 2010-11-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-04-20
相关资源
最近更新 更多