为什么添加一些包会破坏我的代码?

时间:2017-06-30 17:33:03

标签: f# nuget packages

我注意到添加包有时会破坏我的代码。正在运行的Seq.replicateList.take等函数会出现红色波浪线并且程序不再运行。这是一个应该复制问题的详细过程(我正在使用VS Community Edition 2017):

1)创建一个项目。

2)Program.fs包含代码:

[<EntryPoint>]
let main argv =
    printfn "%A" argv
    0 // return an integer exit code

3)按如下方式添加两行代码:

[<EntryPoint>]
let main argv =
    let repla = Seq.replicate 10 "A"
    printfn "%A" (repla |> List.ofSeq |> List.take 5)
    printfn "%A" argv
    0 // return an integer exit code

3)点击Ctrl+F5,程序运行没有任何问题。

4)右键点击References上的Solution Explorer。点击Manage Nuget Packages...

5)点击Browse

6)搜索Newtonsoft.Json并安装它。

7)点击Ctrl+F5,程序运行没有任何问题。控制台打印

["A"; "A"; "A"; "A"; "A"]
[||]

8)按照步骤4到6进行操作,并使用MathNet.Numerics安装包Nuget

9)点击Ctrl+F5,程序运行没有任何问题。控制台打印

["A"; "A"; "A"; "A"; "A"] [||]

10)按照步骤4到6进行操作,并使用MathNet.Numerics.FSharp安装包Nuget

11)单击Program.fs选项卡。在Seq.replicate and List.take`下出现了可怕的红色波浪线。

12)点击Ctrl+F5。弹出一个对话框,显示以下消息:

There were build errors. Would you like to continue and run the last successful build?

问题:

a)到底发生了什么?

b)这是一个与MathNet.Numerics.FSharp中的问题或安装的软件包的特定组合或它们的安装顺序相关的独立案例吗?或者这是一个常见的问题吗?

c)使用Nuget时是否可以避免此问题?

d)如果没有,是否可以通过其他方式(不是Nuget)安装来避免这个问题?

2 个答案:

答案 0 :(得分:6)

MathNet.Numerics.FSharp依赖于FSharp.Core.3.1.2.5,它取代了您正在使用的FSharp.Core的当前版本。年纪很大3.1.2.5缺乏很多功能。

其他流行的F#库也会发生这种情况,例如FsCheck。我通常会将引用更改为FSharp.Core的最新版本,因为它应该向后兼容。

为此,我卸载F#项目并将项目文件中的FSharp.Core引用更新为:

<Reference Include="FSharp.Core">
  <Name>FSharp.Core</Name>
  <AssemblyName>FSharp.Core.dll</AssemblyName>
  <HintPath>$(MSBuildProgramFiles32)\Reference Assemblies\Microsoft\FSharp\.NETFramework\v4.0\$(TargetFSharpCoreVersion)\FSharp.Core.dll</HintPath>
</Reference>

然后我重新加载项目。

由于这是一个相当笨重的程序,希望更有洞察力的用户会发布更好的解决方案。

答案 1 :(得分:3)

嗯,我认为OP的担忧有点有效。我不鼓励手工编辑fsproj文件。而且评论也非常有效,Paket是一个很好的工具,可以简化VS和Code中的依赖管理。所以这里有一个非常简单的两部分答案,其中a)你实际上可以使用nugget使你的解决方案工作,而无需手动编辑项目文件,以及b)快速介绍如何在VS上使用paket。

这个问题,其中一些软件包下载和旧的依赖关系会混淆其他代码,这可能是由于依赖于最小可行版本的策略。您的问题与此问题有点相似:Why can't I get suave to work

这是使用nugget的最简单的解决方案:

  1. 使用fsharp控制台项目打开新解决方案
  2. 此时VS1717中的Fsharp.Core将为4.1:
  3. enter image description here

    1. 现在通过nugget添加Mathnet.Numerics.Fsharp:
    2. enter image description here

      现在,非常不幸的是你被降级为F#3.1

      1. 这不好,所以也可以通过金块得到Fsharp.Core!
      2. enter image description here

        1. 瞧,你回到了一个有效的解决方案,无需编辑fsproj。基本上你所要做的就是添加Fsharp.Core包。您还可以在属性中更改.NET Framework选项,并使用Fsharp 4.1将其移至.NET 4.7:
        2. enter image description here

          现在对于Paket的答案的第2部分(顺便说一句,Paket插件刚刚更新,我测试了它工作正常)。您基本上可以将其用作块的替代品或直接编辑文件。实际上,您需要使用解决方案根目录中的两个文件paket.dependencies和项目根目录中的paket.references。将生成Paket.lock。这是一个两步入门的过程。参加上面的项目,然后从VS的“工具”菜单中选择Paket Dependencies Manager,执行Initialize Paket,然后执行Convert From Nuget

          enter image description here

          有了这个,您可以继续使用nuget管理您的依赖项,或者如果您愿意,可以使用paket。接下来,我将向参考添加Newtonsoft.JSON。双击paket.dependencies文件并添加以下行:nuget Newtonsoft.Json 10.0.3 restriction: >= net452,您实际上只需要Newtonsoft.Json,但我们不想下载名为.NetCore的整个interweb。同时将此行添加到paket.references(您只需在项目资源管理器中单击它):Newtonsoft.Json。并运行工具| Paket |安装:

          Paket.dependencies:

          enter image description here

          Paket.references:

          enter image description here

          运行Paket安装:

          enter image description here

          您将安装Newtonsoft.JSON。通常您不需要指定框架限制的版本,但是它有一些您可能不需要的预发行包,而且我假设您不需要.netcore依赖项。

          您实际上可以右键单击并尝试从引用“添加包”菜单中安装此包,但是您将遇到依赖性错误。

          enter image description here

          enter image description here