10

我想使用 F# 3.0 类型提供程序机制基于“弱”类型的数据源生成“强”类型。在仅安装 .Net 4.0 而不是 .Net 4.5 的环境中,必须可以从 C# 客户端访问生成的类型。如果无法与 .Net 4.0 兼容,我们就不能在当前的大型 ERP 项目中使用类型提供程序。

到目前为止,我已经按照msdn 上的教程(“提供生成的类型”部分),使用ProvidedTypeDefinitionF# 3.0 示例包中的“ProvidedTypes-0.2.fs”中的教程成功创建了 MyGeneratedTypes.dll。(为了让它工作,我必须File.Delete从“ ProvidedTypeDefinition.ConvertToGenerated...”方法中删除“...”行)。

MyGeneratedTypes.dll 有运行时版本v4.0.30319,可以(.Net 4.0 的运行时)。我可以在 C#/.Net 4.0 应用程序中添加对 MyGeneratedTypes.dll 的引用,并且 IntelliSense 会按预期显示类型和成员。但是,当我尝试编译时,C# 编译器失败并产生“警告 MSB3258:无法解析主引用“MyGeneratedTypes”,因为它间接依赖于 .NET Framework 程序集“FSharp.Core,Version=4.3.0.0 , Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a”,在当前目标框架中,“4.3.0.0”版本比“4.0.0.0”版本高。

查看 IL Spy 确认 MyGeneratedTypes.dll 确实包含对 FSharp.Core 4.3 的引用,尽管此引用完全没有必要。到目前为止,我还没有发现任何方法可以阻止 F# 编译器将此引用放入生成的程序集中。(除此之外,我在 C# 中创建了一个纯 .Net 4.0 程序集并将其传递给 的构造函数ProvidedTypeDefinition,但这没有影响)。

有谁知道a)如何摆脱引用,或者b)如果这只是一个F# 3.0候选版本问题,将在最终版本中解决。

编辑

与@Brian 的对话导致了以下问题的“部分”解决方案:您可以编译引用具有 F# 3.0 生成类型的库的“纯 C#/.Net 4.0”客户端,但只能通过调用 .Net 4.0 C# 编译器( csc ) 直接从命令行。在 VS 2010 中或通过 MSBuild 命令行编译时,它不起作用。我怀疑这是由以下行为引起的:

  1. MyGeneratedTypes.dll 在 VS 2012 中使用 F# 类型提供程序机制生成。
  2. 在生成过程中,会自动插入对 FSharp.Core 4.3 的引用(即使不需要),而无需在依赖项的元数据中指定“SpecificVersion:true”。
  3. “.Net 4.5-free”系统上的 VS 2010 中的 AC# 客户端引用 MyGeneratedTypes.dll。
  4. 编译 C# 客户端时,MSBuild 会在 MyGeneratedTypes.dll 中发现对 FSharp.Core 4.3 的间接引用。
  5. 因为间接引用存在于“SpecificVersion:false”中,所以 MSBuild 发出警告MSB3257并拒绝将直接引用 /r:"MyGeneratedTypes.dll" 传递给 C# 编译器 (csc)。(注意:不能以任何方式抑制 MSBuild 警告。)
  6. C# 编译器 (csc) 由 MSBuild 调用,不带 /r:"MyGeneratedTypes.dll"。因此,它无法编译,并发出编译器错误 CS0246:“找不到类型或命名空间名称 'MyGeneratedTypes' (...)”。

据我所知,除非修改 F# 类型提供程序机制 a) 在生成的程序集中不需要时排除对 FSharp.Core 4.3 的引用,或者 b) 包含参考元数据“ SpecificVersion:true”。

4

1 回答 1

6

只需在 C# 项目中添加对 FSharp.Core 4.3.0.0 的引用(或忽略警告)。尽管编号约定很奇怪,但 FSharp.Core 4.3.0.0 不依赖于 .Net 4.5 中的任何内容,它只依赖于 .Net 4.0。

于 2012-06-20T18:22:19.123 回答