如何创建一个可从C#使用的F#类型提供程序?

28

如果我使用F# Type Providers来自FSharp.Data.TypeProviders 4.3.0.0的程序集,我可以在一个非常简单的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<br>type PhoneNumberRegEx = CheckedRegexProvider< @"(?<AreaCode>^\d{3})-(?<PhoneNumber>\d{3}-\d{4}$)">
open Samples.FSharp.MiniCsvProvider<br>type csv = MiniCsvProvider<"a.csv">

它最后是在2011年3月发布的,我的猜测是它们还没有反映出随Visual Studio 2012一起发货的type provider的最终版本。

F# Type Providers看起来是一项伟大的技术,但我们需要帮助来构建它们。任何帮助都将不胜感激。

1个回答

39
标准类型提供程序(针对OData、LINQ to SQL和WSDL)适用于C#的原因是它们在幕后生成真正的.NET类型。这被称为“生成式类型提供程序”。事实上,它们只是调用代码生成工具,如果您以标准方式从C#使用这些技术,就会调用该工具。因此,这些类型提供程序只是一些标准.NET工具的包装器。
大多数新编写的提供程序都是作为“擦除式类型提供程序”编写的。这意味着它们只生成“虚假”的类型,告诉F#编译器可以调用哪些成员等等,但是当编译器编译它们时,“虚假”类型将被替换为其他代码。这就是为什么在使用库时无法看到任何类型的原因 - 没有任何类型实际存在于编译代码中。
除非您正在包装现有的代码生成器,否则编写“擦除式类型提供程序”更容易,因此大多数示例都是以这种方式编写的。擦除式类型提供程序还有其他好处 - 即它们可以生成大量的“虚假”类型而不会生成过大的程序集。
无论如何,在MSDN教程中有一篇简短的笔记"提供生成的类型",其中提供了一些编写生成式提供程序的提示。然而,我预计大多数新的F#类型提供程序都将被编写为擦除式。它指出,您必须拥有一个真正的.NET程序集(具有生成的类型),而F#用于构建类型提供程序的帮助程序并没有简化此过程 - 因此,您需要发出程序集的IL或生成C#/F#代码并将其编译(即使用CodeDOM或Roslyn)。

1
作为生成类型提供程序的微型示例,可以查看 Codeplex 上 ProvidedTypes API 的测试集(http://fsharp3sample.codeplex.com/)。 - desco
4
谢谢Tomas,这绝对有助于我理解类型提供程序。我成功地在VS 2012中使用生成式类型提供程序,并将其用于创建F#库中的类型以及从C#应用程序中使用该库。所有代码都在GitHub中,我在博客文章中记录了一些我在过程中学到的东西:http://blog.ctaggart.com/2012/08/how-do-i-create-f-type-provider-that.html - Cameron Taggart
你好。F# 3.0专家第468页。使用VS '12 Pro。Fsharpx.TypePoviders.XAML在VS'12Pro中的状态如何?它只能与Express一起使用吗?Pro和Express能够良好地协同工作吗? - Art Scott
Lamar项目使用Roslyn在内存中编译生成的类型(请参阅此处的LamarCodeGeneration和LamarCompiler:https://jasperfx.github.io/lamar/documentation/compilation/)。这似乎是启用C#工具的不错起点。在GitHub讨论区提到了这一点:https://github.com/dotnet/csharplang/issues/236#issuecomment-591652505。 - lightw8

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接