28

如果我使用程序集 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# 访问。我的猜测是它们是擦除类型而不是生成类型。我仍然有点模糊哪个是哪个,但它在这里定义为

  1. 生成的类型是嵌入到使用类型提供程序的程序集中的真实 .NET 类型(这是包装代码生成工具(如 sqlmetal)使用的类型提供程序)
  2. 擦除类型是在编译代码时由其他类型表示的模拟类型。

MSDN教程中提到的F# 3.0 示例包中的示例不适用于我。它们构建,但是当我尝试使用它们时,我得到了错误。

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# Type Providers 看起来是一项很棒的技术,但我们需要帮助来构建它们。任何帮助表示赞赏。

4

1 回答 1

39

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

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

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

Anyway, there is a brief note "Providing Generated Types" in the MSDN tutorial, which has some hints on writing generative providers. However, I'd expect most of the new F# type providers to be written as erasing. It notes that you must have a real .NET assembly (with the generated types) and getting that is not simplified by the F# helpers for building type providers - so you'll need to emit the IL for the assembly or generate C#/F# code and compile that (i.e. using CodeDOM or Roslyn).

于 2012-08-25T03:38:21.973 回答