如何使用F#3.0类型提供程序生成C#友好,.Net 4.0兼容类型 [英] How to generate C#-friendly, .Net 4.0 compatible types using F# 3.0 type providers

查看:56
本文介绍了如何使用F#3.0类型提供程序生成C#友好,.Net 4.0兼容类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I want to generate "strong" types based on "weakly" typed data sources, using the F# 3.0 type provider mechanism. The generated types must be accessible from C# clients in an environment where only .Net 4.0 is installed, but not .Net 4.5. If .Net 4.0 compatibility is not possible, we cannot use type providers in our current large-scale ERP project.

到目前为止,通过遵循ProvidedTypeDefinition(是F#3.0示例包的一部分)在msdn上创建rel ="nofollow">教程(提供生成的类型"一节). (为了使其正常工作,我必须从"ProvidedTypeDefinition.ConvertToGenerated ..."方法中删除"File.Delete ..."行).

So far, I have succeeded in creating MyGeneratedTypes.dll by following the tutorial on msdn (section "Providing Generated Types"), using the ProvidedTypeDefinition from "ProvidedTypes-0.2.fs", which is part of the F# 3.0 sample pack. (In order for it to work, I had to remove the line "File.Delete..." from the "ProvidedTypeDefinition.ConvertToGenerated..." method).

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"更高.'

MyGeneratedTypes.dll has runtime version v4.0.30319, which is OK (the runtime of .Net 4.0). I can add a reference to MyGeneratedTypes.dll in a C#/.Net 4.0 application, and IntelliSense shows the types and members as expected. However, when I try to compile, the C# compiler fails and produces 'warning MSB3258: The primary reference "MyGeneratedTypes" could not be resolved because it has an indirect dependency on the .NET Framework assembly "FSharp.Core, Version=4.3.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" which has a higher version "4.3.0.0" than the version "4.0.0.0" in the current target framework.'

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

A look at IL Spy confirms that MyGeneratedTypes.dll indeed contains a reference to FSharp.Core 4.3, eventhough this reference is completely unnecessary. So far, I have found no way to prevent the F# compiler from putting this reference into the generated assembly. (Among other things, I have created a pure .Net 4.0 assembly in C# and passed it to the constructor of ProvidedTypeDefinition, but this has no influence).

有人知道a)如何摆脱引用,或b)如果这只是F#3.0发行候选版本的问题,将在最终发行版中解决.

Does anybody know a) how to get rid of the reference, or b) if this is only an F# 3.0 release candidate problem, which will be solved in the final release.

修改

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

The conversation with @Brian has resulted in the following "partial" solution to the problem: You can compile a "pure C#/.Net 4.0" client referencing a library with F# 3.0 generated types, but only by calling the .Net 4.0 C# compiler (csc) directly from the command line. It does not work when compiling in VS 2010 or via MSBuild command line. I suspect this is caused by the following behavior:

  1. MyGeneratedTypes.dll是在VS 2012中使用F#类型提供程序机制生成的.
  2. 在生成过程中,将自动插入对FSharp.Core 4.3的引用(即使不需要),而无需在依赖项的元数据中指定"SpecificVersion:true".
  3. VS 2010中".Net 4.5-free"系统上的C#客户端引用MyGeneratedTypes.dll.
  4. 编译C#客户端时,MSBuild在MyGeneratedTypes.dll中发现对FSharp.Core 4.3的间接引用.
  5. 因为间接引用以"SpecificVersion:false"存在,所以MSBuild发出警告 MSB3257 ,并拒绝将直接引用/r:"MyGeneratedTypes.dll传递给C#编译器(csc). (注意:不能以任何方式禁止MSBuild警告.)
  6. MSBuild调用C#编译器(csc),不带/r:"MyGeneratedTypes.dll.因此,它无法编译,并发出编译器错误CS0246:找不到类型或名称空间名称'MyGeneratedTypes'(...)".
  1. MyGeneratedTypes.dll is generated in VS 2012 with the F# type provider mechanism.
  2. During generation, a reference to FSharp.Core 4.3 is automatically inserted (even if not needed), without specifying "SpecificVersion:true" in the metadata for the dependency.
  3. A C# client in VS 2010 on a ".Net 4.5-free" system references MyGeneratedTypes.dll.
  4. When the C# client is compiled, MSBuild discovers the indirect reference to FSharp.Core 4.3 inside MyGeneratedTypes.dll.
  5. Because the indirect reference exists with "SpecificVersion:false", MSBuild emits the warning MSB3257 and refuses to pass the direct reference /r:"MyGeneratedTypes.dll" to the C# compiler (csc). (Note: MSBuild warnings cannot be suppressed in any way.)
  6. The C# compiler (csc) is called by MSBuild, without /r:"MyGeneratedTypes.dll". Therefore, it cannot compile, and emits compiler error CS0246: "The type or namespace name 'MyGeneratedTypes' could not be found (...)".

据我所知,除非修改F#类型提供程序机制,否则我们将一直陷于此问题;或者a)在生成的程序集中不需要对FSharp.Core 4.3的引用时,将其排除在外;或者b)包含带有元数据"SpecificVersion:true"的引用.

As far as I can tell, we're stuck with this problem unless the F# type provider mechanism is modified either a) to exclude the ref to FSharp.Core 4.3 when it is not needed in a generated assembly, or b) to include the ref with the metadata "SpecificVersion:true".

推荐答案

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

Just add a reference to FSharp.Core 4.3.0.0 in the C# project (or ignore the warning). Despite the weird numbering convention, FSharp.Core 4.3.0.0 does not depend on anything in .Net 4.5, it only depends on .Net 4.0.

这篇关于如何使用F#3.0类型提供程序生成C#友好,.Net 4.0兼容类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆