F#类型提供程序可以被整合到C#中吗?

41

酷炫新颖的F# 3.0功能类型提供程序可用于弥合F#数据类型或类与数据源结构(如XML或WSDL)之间的不匹配。然而,在其他.NET语言(如C#)中,这种不匹配也是一个挑战。

我想在C#代码中使用F# 3.0提供程序。如果有可能,我该怎么做?如果不能,那么C#实现需要具备哪些能力才能使用它们?


2
这应该是以社区维基的形式呈现。我相信它会引发相当长时间的讨论。 - Eriawan Kusumawardhono
2个回答

29

我认为@kvb给出了一些技术难点的概述,我同意类型推断会有问题 - 你基本上只能在本地使用由提供程序生成的类型,类似于匿名类型。我认为C#可能会在Roslyn中提供类似的功能,但我怀疑它不会像在F#中那样优雅和平滑地集成(在F#中,类型提供程序实际上是语言特性而不仅仅是工具)。

回答您的两个具体问题:

 

[我如何]在C#代码中使用F# 3.0提供程序?

F#类型提供程序实际上只能由F#编译器理解,因此您需要从F#中使用它们。对于生成型提供程序(SQL,实体,WSDL,配置文件),您可以从F#引用提供程序,并从C#项目中使用生成的类型。

对于删除类型提供程序,您将无法做到这一点,因为这些类型并不存在,只有F#才能看到它们。因此,最好的选择是在F#中编写处理代码,并将结果作为记录或其他易于从C#中消耗的类型的集合返回。

 

一个C#实现需要什么才能使用它们?

当然,我可以只说“C#必须支持类型提供程序!”,但这里还有一些更多的想法。类型提供程序只是.NET程序集,它们不使用任何特定于F#的类型。任何.NET语言(包括C#)都可以使用ITypeProvider接口,因此,如果C#设计人员希望,他们可以重用已经为F#构建的所有优秀提供程序。

因此,将这个建议提交到C#用户声音或者在其他地方提出(或者说服Mono团队实现这一点!),也许它会被添加到C#(vNext + 1 + ...)中。目前,你只能在F#中获得所有的好处。

感谢您的反馈。我不确定我是否完全理解生成型和擦除型提供程序之间的区别。您知道在哪里可以找到有关此主题的其他信息吗?我猜世界银行类型提供程序是擦除型提供程序的一个例子。但CSV类型提供程序呢?它也是擦除型提供程序吗? - carstenj
所以最好的选择是用 F# 编写处理代码,并将结果作为记录集合或其他易于从 C# 消耗的类型返回。您是否有此类代码示例? 抱歉,我不能提供代码示例,因为我的能力仅限于文本翻译。 - M.Y. Babt
1
@Nameless,我在Pluralsight上制作了一个视频:https://www.pluralsight.com/courses/accessing-data-fsharp-type-providers。实际上,在接下来的两天内它是免费的(但你以后也应该能够获得免费试用)。 - Tomas Petricek
@TomasPetricek 太棒了!谢谢你,Tomas! - M.Y. Babt

9
一些类型提供程序的工作方式是特别为F#程序员定制的,但在考虑强类型数据访问解决方案时,可能不太令人信服。例如,很多F#编程是在F# Interactive中完成的,而类型提供程序与代码生成器相比(需要一种语言外部机制来生成源代码文件),可以非常好地支持这种工作流。由于C#程序员习惯于较慢的编辑-编译-运行周期,因此在C#环境中,这可能不那么重要。
从技术角度来看,我认为F#更普遍的类型推断可能是与C#等语言相比最大的优势。例如,如果我想将一些类型提供程序的数据访问逻辑封装在另一个类型中,我可以像这样做:
let moviesStartingWith prefix =
    query {
        for movie in MyDataSource.Movies do
        where (movie.Title.StartsWith(prefix) }
    |> Seq.toList

在C#中,我需要指定返回类型(例如List<DataSource.ServiceTypes.Movie>),这会变得很麻烦,即使使用IntelliSense,我也需要浏览提供的类型集来生成签名,以及浏览提供的值集来生成查询。当然,这也适用于除了类型提供程序之外的其他领域,但是我认为对于某些提供程序自然生成的嵌套类型层次结构,这在实践中尤其痛苦,因为类型名称变得极长。

2
C#类型推断可能比你想象的要好。即使这是一个方法而不是内联语句,我们也可以在方法签名上放置一个类型参数,将MyDataSource.Movies传递进去会绑定类型参数,而无需指定闭合类型,并且保留返回类型为List<T> - codekaizen

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