预定义类型'System.ValueTuple´2´'未定义或未导入。

430

我已经安装了Visual Studio 15 Preview 3,并尝试使用新的元组功能。

static void Main(string[] args)
{
    var x = DoSomething();
    Console.WriteLine(x.x);
}

static (int x, int y) DoSomething()
{
    return (1, 2);
}

编译时出现错误:

预定义类型 'System.ValueTuple´2´ 未定义或未导入

根据博客文章,这个功能应该默认为“开启”状态。

我做错了什么?


3
有人知道在针对4.6.2版本的2017 RTM中,是否仍需要NuGet包吗?看起来你仍然需要它,我本来以为在最终版本中不需要。 - dmeglio
你可以尝试使用 System.Tuple<int, int> 替代。 - Kevin Xiao
对我来说,这个 https://dev59.com/UFcP5IYBdhLWcg3wHm1U#46533630 是解决方案。 - Andre
10个回答

571

对于 .NET 4.6.2 或更低版本,.NET Core 1.x 和 .NET Standard 1.x,您需要安装 NuGet 包 System.ValueTuple

Install-Package "System.ValueTuple"

或者在VS 2017中使用包引用:

<PackageReference Include="System.ValueTuple" Version="4.4.0" />

.NET Framework 4.7、.NET Core 2.0和.NET Standard 2.0都包含这些类型。


3
谢谢。这是否意味着它能与4.6.2一起使用?调试器仍显示x.Item1和x.Item2,而不是(x.x and x.y)。你知道这是否会改变吗? - gsharp
2
安装程序包 "System.ValueTuple" - 包括预发行版本 - Frison Alexander
15
好的,它似乎不在4.6.2版本中。 - binki
13
可以使用4.6.2版本,但仍需要安装这个软件包。 - Eli
10
在.NET 4.7中,该软件包已经被原生地包含了。 - Mafii
显示剩余6条评论

47

这是 .NET Framework 4.7 的一部分。

只要您不针对上述框架或更高版本(或者 .NET Core 2.0 / .NET Standard 2.0),您将需要引用 ValueTuple。通过添加 System.ValueTuple NuGet Package 进行操作。


1
我刚刚尝试了使用 .net 4.7,但它没有起作用。找不到“System.ValueTuple`2”。 - Bidou
我已经安装了.NET Framework 4.7和Visual Studio的目标包。我还在下拉菜单中选择了版本4.7,但它仍然无法编译。 - Bidou
13
好的,我发现问题所在:我的项目文件(csproj)中硬编码了dll文件System.ValueTuple。将该条目从项目文件中删除后,问题得到解决。 - Bidou
1
不错的解决方案,但你可以添加更多细节。在我的情况下,System.ValueTuple.dll仍然停留在我的bin文件夹中。一旦我删除了它,一切就正常了。我的语言版本是"default",一切都正常运作。 - toddmo

14

5

使用内置的终端,在 Visual Studio Code 中运行以下命令:

dotnet add package "System.ValueTuple"

别忘了在此之后运行dotnet restore


我无法在VS Code中使其正常工作。 - JonathanPeel
11
注意:不要在 .Net 4.7 中这样做。 - toddmo

4
我也遇到了这个问题,当我从.NET 4.6.2升级到.NET 4.7.2时。不幸的是,我无法删除对System.ValueTuple的包引用,因为我使用的另一个NuGet包依赖于它。
最终,我能够找到根本原因:在项目文件夹中存在一个.NET 4.6.2版本的mscorlib.dll(发布操作的输出),MSBuild决定引用此程序集,而不是位于C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.7.2的官方.NET 4.7.2参考程序集。
由于System.ValueTuple是在.NET 4.7中引入的,所以MSBuild在.NET 4.6.2的参考程序集中找不到该类型而导致编译失败。
https://dev59.com/3VkR5IYBdhLWcg3w0AGy#57777123的副本)

3

2
即使使用.NET 4.6.2,似乎仍需要System.ValueTuple包。 - HaveSpacesuit
3
好的,我会尽力进行翻译。以下是需要翻译的内容:@mrsundquist,是的,任何评分低于4.7的东西。 - toddmo

3

如果其他人遇到同样的问题,我在将项目更新为4.7后遇到了这个错误。奇怪的是,我必须删除System.ValueTuple引用才能消除此错误。


2
我不建议将ValueTuple作为.NET Framework项目的软件包引用添加。如您所知,此程序集可从4.7 .NET Framework中获得。
在某些情况下,您的项目会尝试以任何代价从.NET Framework文件夹中包含ValueTuple,而不是软件包文件夹,并且这可能会导致一些程序集未找到错误。
今天我们在公司遇到了这个问题。我们有一个包含2个项目的解决方案(我进行了简化):
- Lib - Web Lib包括ValueTuple并且Web正在使用Lib。结果发现,由于某种未知的原因,在尝试解析ValueTuple路径时,Web会将HintPath指向.NET Framework目录,并且会使用不正确的版本。我们的应用程序因此崩溃。对于Web.csproj文件或该程序集的HintPath都没有定义ValueTuple。问题非常奇怪。通常它会从软件包文件夹复制程序集。但这次不是正常的。
对我来说,始终存在着将System.*软件包引用添加到项目中的风险。它们通常就像定时炸弹。它们在开始时很好,但它们可能会在最糟糕的时刻爆炸。我的经验法则是:如果没有真正需要,不要为.NET Framework使用System.* Nuget软件包。
我们通过在Web项目的.csproj文件中手动添加ValueTuple来解决了问题。

0

我需要检查 System.ValueTuple.dll 文件是否在源代码控制下,并在 .cssproj 文件中正确引用它:

  1. 右键单击解决方案中的每个项目
  2. 卸载项目
  3. 编辑 .cssproj 文件:更改

< Reference Include="System.ValueTuple" >

< HintPath >

....\ProjectName\ProjectName\obj\Release\Package\PackageTmp\bin\System.ValueTuple.dll

< /HintPath >

< /Reference >

< Reference Include="System.ValueTuple" >

< HintPath >

..\packages\System.ValueTuple.4.4.0\lib\netstandard1.0\System.ValueTuple.dll

< /HintPath >

< /Reference >

  1. 保存更改并重新加载项目
  2. 找到 System.ValueTuple.dll 并将其保存到此文件夹中
  3. 将此文件的引用添加到源代码控制中

(可选):7. 以同样的方式解决其他 .dll 文件的问题


1
硬编码固定的文件路径(或任何字符串)从来不是一个好的解决方案。 - Arghya C

0
我们在一个旧项目中遇到了同样的问题,该项目针对Framework 4.5.2进行了定位。我尝试了包括上面列出的所有方案:定位到4.6.1,添加System.ValueTuple包,删除bin、obj和.vs文件夹。没有用。重复相同的过程,针对4.7.2进行操作。然后尝试删除System.ValueTuple包,因为有一位评论者建议我针对4.7.2进行操作。仍然没有效果。检查csproj文件引用路径。看起来没问题。甚至回退到4.5.2并重新安装包。所有这些都伴随着多次VS重启和多次删除相同文件夹。真的什么都没用。
我不得不重构使用结构体。我希望其他人在未来不会继续遇到这个问题,但如果你像我们一样陷入困境,这可能会有所帮助。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接