【问题标题】:c# 7 tuples not working (roslyn compiler exception)c# 7 tuples 不工作(roslyn 编译器异常)
【发布时间】:2017-11-15 10:54:44
【问题描述】:

一段时间以来,我们在 razor 文件中使用了一些新的 c# 7.0 功能。我们已将 Roslyn 编译器集成到我们的 Web 项目中,这些项目目前针对 .NET Framework 4.6.2。

今天我想在剃须刀文件中试用tuples,如下所示:

@functions
{
    public (string labelName, string sfName) GetNames(PurchaseType purchaseType)
    {
        switch (purchaseType)
        {
            case PurchaseType.New:
                return (labelName: Booklist.New, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxNew);
            case PurchaseType.Rental:
                return (labelName: Booklist.Rent, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxRental);
            case PurchaseType.SecondHand:
                return (labelName: Booklist.Secondhand, sfName: SpecflowIdentifiers.BooklistItem.CheckBoxSecondHand);
            default:
                throw new ArgumentOutOfRangeException(nameof(purchaseType), @"should not get here");
        }
    }
}

@helper RenderCheckbox(PurchaseType purchaseType, int index, decimal priceTo)
{
    var names = GetNames(purchaseType);
    var x = name.labelName;
    // render something
}

这会产生以下运行时异常:

CS8137:无法定义使用元组的类或成员,因为找不到编译器所需的类型“System.Runtime.CompilerServices.TupleElementNamesAttribute”。您是否缺少参考资料?

CS8179:未定义或导入预定义类型“System.ValueTuple`2”

这使我找到了https://stackoverflow.com/a/40826779/2772845,其中提到我应该将 System.ValueTuple 包添加到项目中。但我已经添加了。

这些是配置中使用的包:

<package id="Microsoft.CodeDom.Providers.DotNetCompilerPlatform" version="1.0.8" targetFramework="net462" />
<package id="Microsoft.Net.Compilers" version="2.4.0" targetFramework="net462" developmentDependency="true" />
<package id="System.ValueTuple" version="4.4.0" targetFramework="net462" />

所以,我现在又开始使用旧的 Tuple&lt;&gt;。 我想知道是否有人知道我忽略了什么。

2017 年 11 月 16 日编辑:

所以我将public (string labelName, string sfName) GetNames(PurchaseType purchaseType) 更改为public ValueTuple&lt;string, string&gt; GetNames(PurchaseType purchaseType),这给了我以下异常:

CS0433:“System.ValueTuple,Version=4.0.2.0,Culture=neutral,PublicKeyToken=cc7b13ffcd2ddd51”和“mscorlib,Version=4.0.0.0,Culture=neutral,PublicKeyToken=b77a5c561934e089”中都存在“ValueTuple”类型

这导致我'ValueTuple<T1, T2>' exists in both 'System.ValueTuple ...' and 'mscorlib ...' 给出了实际答案。我已经安装了 .NET Framework 4.7,并且由于 razor 是在运行时编译的,所以它只使用该版本。

亲切的问候, 瑞克

【问题讨论】:

  • 你直接使用 ValueTuple 会怎样?
  • 谢谢,通过更改我的代码,我发现了实际问题。我已经用调查结果更新了我的帖子。

标签: c# razor tuples roslyn c#-7.0


【解决方案1】:

Razor 视图由 ASP.Net 在运行时编译,不会自动从您的项目继承引用或其他设置。

你需要在Web.config的ASP.Net运行时编译中添加System.ValueTuple:

<system.web>
    <compilation>
      <assemblies>
        <add assembly="System.ValueTuple" />

【讨论】:

  • 我已经添加了配置。但是编译器还是给出了同样的异常。
【解决方案2】:

这似乎是 Razor 的好地狱。 首先,如果您的目标是 .NET 4.7 或更高版本,则不应引用 System.ValueTuple,因为所有需要的类型都已经是 mscorlib 的一部分。 但在我看来,Razor 以某种方式使用了最新版本的 mscorlib,即使您专门针对例如.NET 4.6.2。 所以在我看来,至少在安装了 .NET 4.7 的系统上,解决方案实际上是删除

 <system.web>
    <compilation>
        <assemblies>
            <add assembly="System.ValueTuple, Version=4.0.2.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51"/>

这样,您当然可以在缺少 .NET 4.7 的服务器上中断应用程序的运行时编译,或者如果您使用它,则进行预编译。

如果至少所有服务器都处于相同状态,则可以使用配置转换。

同时检查 web.configs 时同时检查 - 根 web.config 和视图文件夹中的 web.config。

如果有人在部署过程中遇到类似的预编译问题,到目前为止,我设法解决的唯一方法是将 System.ValueTuple 的引用直接添加到 CSC 命令行,如下所示:

<system.codedom>
    <compilers>
        <compiler extension=".cs" compilerOptions='/langversion:7 /nowarn:1659;1699;1701 /R:"../packages\System.ValueTuple.4.4.0\lib\net461\System.ValueTuple.dll"' xdt:Locator="Match(extension)" xdt:Transform="SetAttributes" />
    </compilers>
</system.codedom>

在服务器部署的转换文件中。 这需要运行时编译,因为它无权访问 ../packages。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-08-11
    • 2016-06-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-01-29
    • 2016-01-07
    相关资源
    最近更新 更多