如何使用F#3.0类型提供程序生成C#友好的.Net 4.0兼容类型

如何使用F#3.0类型提供程序生成C#友好的.Net 4.0兼容类型,f#,type-providers,f#-3.0,F#,Type Providers,F# 3.0,我想使用F#3.0类型提供程序机制,基于“弱”类型的数据源生成“强”类型。在只安装了.Net 4.0而没有安装.Net 4.5的环境中,必须可以从C#客户端访问生成的类型。如果.Net 4.0不兼容,我们就不能在当前的大型ERP项目中使用类型提供程序 到目前为止,我已经通过遵循msdn上的“提供生成的类型”部分,使用“ProvidedTypes-0.2.fs”中的ProvidedTypeDefinition成功创建了MyGeneratedTypes.dll,这是F#3.0示例包的一部分。(为了让

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

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

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

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

  • 据我所知,除非F类型提供程序机制被修改为a)在生成的程序集中不需要时排除对FSharp.Core 4.3的引用,或者b)在元数据“
    SpecificVersion:true
    ”中包含对FSharp.Core 4.3.0.0的引用,否则我们将无法解决这个问题(或忽略警告).尽管有奇怪的编号约定,但FSharp.Core 4.3.0.0并不依赖于.Net 4.5中的任何东西,它只依赖于.Net 4.0。

    我没有答案,但我很好奇-如果要从C使用库,为什么要使用F类型提供程序?你打算将来转移到F吗?因为如果不是,使用CodeDOM或Roslyn可能是解决这个问题的更简单的方法。我认为类型提供程序的大部分价值来自于使用F#…@Tomas。我们在解决方案的非UI部分使用F#作为附加语言,它主要由许多C#项目组成。我希望类型提供程序提供一种创建CLI类型生成器的简化方法(通过使用F#引号和提供的typedefinition的简化API)。到目前为止,我喜欢我看到的,但它没有用C#编译(还没有?)。多年来,我们一直在使用自制的生成器生成C#源代码文件,这很难维护。如果类型提供程序不起作用,我将研究CodeDom和Roslyn——谢谢你的建议。我已经尝试过了。无论如何,C#编译器都会给出两个错误,说它在gen中找不到名称空间和类型已编译的程序集,虽然两者都通过C#IntelliSense完全可见(在C#编码时没有问题,只有在C#编译时)。C#编译器发出的唯一其他消息是“内部F#引用”警告,根据您的回答,这是无害的。在IL Spy中,除了F#引用之外,程序集看起来正常。如果内部F#引用不是问题的根本原因,我不知道还有什么可能…好的,分享您得到的实际编译器错误会很有帮助。所以您是说ildasm/ilspy请查看这些公共类型出现在F#程序集中,但由于某种原因,C#编译器没有“看到”它们,即使程序集在csc.exe命令行上引用了“/r”?是的,我就是这么说的。C#/.Net 4.0客户端在存在.Net 4.5的Windows 8上运行良好。但是,它在只有.Net 4.0的Windows 7上不工作。这里,C#ompiler发出两条消息:1)“错误CS0”