如何创建可以在C#中使用的F#类型提供程序?

时间:2012-08-25 03:14:48

标签: f# type-providers

如果我使用程序集FSharp.Data.TypeProviders 4.3.0.0中的F#Type Providers,我可以在一个非常简单的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);
}

我无法找到任何有关如何创建这样的类型提供程序的工作示例。无法从C#访问FSharpx.TypeProviders中的类型提供程序。我的猜测是它们是擦除类型而不是生成类型。我仍然有点模糊,但是它是defined here as

  1. 生成的类型是嵌入到使用类型提供程序的程序集中的真实.NET类型(这是包装代码生成工具的类型提供程序,如sqlmetal使用)
  2. 删除类型是模拟类型,在编译代码时由其他类型表示。
  3. 来自MSDN F# 3.0 Sample Pack中提及的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月,我的猜测是它们尚未反映Visual Studio 2012附带的类型提供程序的最终版本。

    F#类型提供商看起来像一项伟大的技术,但我们需要帮助构建它们。任何帮助表示赞赏。

1 个答案:

答案 0 :(得分:36)

标准类型提供程序(对于OData,LINQ to SQL和WSDL)与C#一起使用的原因是它们在封面后面生成真正的.NET类型。这称为生成类型提供程序。事实上,如果您以标准方式使用C#中的这些技术,他们只需调用代码生成工具即可。因此,这些类型提供程序只是一些标准.NET工具的包装。

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

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

无论如何,有一个简短的注释"Providing Generated Types" in the MSDN tutorial,它有一些关于编写生成提供者的提示。但是,我希望大多数新的F#类型提供程序都可以写成擦除。它指出你必须拥有一个真正的.NET程序集(使用生成的类型)并且F#帮助程序不会简化构建类型提供程序 - 因此您需要为程序集发出IL或生成C#/ F#代码并编译(即使用CodeDOM或Roslyn)。