Skip to main content
 首页 » 编程设计

f#之如何创建可从 C# 使用的 F# 类型提供程序

2024年11月01日16zlslch

如果我使用程序集 FSharp.Data.TypeProviders 4.3.0.0 中的 F# 类型提供程序,我就能够在一个非常简单的 F# 库中创建类型。然后我就可以在不依赖程序集 FSharp.Data.TypeProviders 的情况下使用这些类型。那真是太甜了!下面是一个例子:

我创建了一个名为 TryTypeProviders 的 F# 库项目。我把它放在 .fs 中:

module TryTypeProviders 
type Northwind = Microsoft.FSharp.Data.TypeProviders.ODataService

然后我就可以使用 C# 项目中的 F# 库:
public static void Main() 
{ 
    var c = new TryTypeProviders.Northwind(); 
    foreach (var cust in c.Customers) 
        Console.WriteLine("Customer is: " + cust.ContactName); 
    Console.ReadKey(true); 
}

我还没有找到任何关于如何创建这样的类型提供程序的工作示例。 FSharpx.TypeProviders 中的类型提供程序不能从 C# 访问。我的猜测是它们是删除类型而不是生成类型。我仍然有点不清楚哪个是哪个,但它是 defined here as :
  • 生成的类型是真正的 .NET 类型,它们嵌入到使用类型提供程序的程序集中(这是包装代码生成工具(如 sqlmetal 使用的类型提供程序)所使用的)
  • 删除类型是模拟类型,在编译代码时由其他类型表示。

  • 来自 F# 3.0 Sample Pack 的样本在 MSDN tutorial 中提到不适合我。它们构建,但是当我尝试使用它们时,我会出错。
    open Samples.FSharp.RegexTypeProvider
    type PhoneNumberRegEx = CheckedRegexProvider< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)">
    open Samples.FSharp.MiniCsvProvider
    type csv = MiniCsvProvider<"a.csv">

    它最后一次发布是在 2011 年 3 月,我猜测它们还没有反射(reflect) Visual Studio 2012 附带的类型提供程序的最终版本。

    F# 类型提供程序看起来是一项很棒的技术,但我们需要帮助构建它们。任何帮助表示赞赏。

    请您参考如下方法:

    标准类型提供程序(用于 OData、LINQ to SQL 和 WSDL)与 C# 一起使用的原因是它们在幕后生成真正的 .NET 类型。这叫做生成式提供程序 .事实上,它们只是调用代码生成工具,如果您以标准方式使用 C# 中的这些技术,就会调用该工具。因此,这些类型提供程序只是一些标准 .NET 工具的包装器。

    大部分新写的provider都写成删除类型提供商 .这意味着它们只生成“假”类型,告诉 F# 编译器可以调用哪些成员(等),但是当编译器编译它们时,“假”类型会被其他一些代码替换。这就是为什么在使用 C# 库时看不到任何类型的原因 - 编译代码中实际上不存在任何类型。

    除非您包装现有的代码生成器,否则编写删除类型提供程序会更容易,因此大多数示例都是以这种方式编写的。删除类型提供程序还有其他好处 - 即它们可以生成大量“假”类型而不会生成过大的程序集。

    不管怎样,有一个简短的说明"Providing Generated Types" in the MSDN tutorial ,其中有一些关于编写生成式提供程序的提示。但是,我希望大多数新的 F# 类型提供程序都写为删除。它指出,您必须有一个真正的 .NET 程序集(带有生成的类型),并且 F# 帮助程序并未简化构建类型提供程序的程序集 - 因此您需要为程序集发出 IL 或生成 C#/F# 代码并编译(即使用 CodeDOM 或 Roslyn)。