设计一个可以从F#中使用的C#库的指南

时间:2013-02-27 13:06:44

标签: c# f#

我只是想指出这个问题不是

的反面

Best approach for designing F# libraries for use from both F# and C#

在这里,我不是要问如何设计一个用于两个世界的C#函数库。

我想了解良好做法,了解设计选择包含或避免以获得合理的妥协,使此库可用于F#

像(例如)的实践:

  • 保持对象层次结构尽可能简单

  • 避免改变对象的状态,但返回新的

  • 等...

任何已经完成它的人都可以分享它的经验吗?

旁注

有趣的是,这个OSS项目IronJS。是的,它是用F#编写的,但是作者公开了两个专门的主持人IronJS.Hosting.FSharpIronJS.Hosting.CSharp

2 个答案:

答案 0 :(得分:4)

与现有.NET库互操作是F#的主要设计目标,因此对要使用的库没有任何限制。

也就是说,由于F#更严格的打字,有些模式导致代码略显笨拙。构建器模式是一个。

var bldr = new StringBuilder();
bldr.Append("abc"); //ignoring return value

VS

bldr.Append("abc") |> ignore //must be explicitly ignored

但是这很容易使用扩展方法或let-bound函数。底线:互操作是F#的优势和最大成就之一。

答案 1 :(得分:4)

想象一下,有一天你想在F#中重写你的C#库以获得更好的可用性。以下是您可能采取的路径:

enter image description here

我专注于“命令性C# - >功能性C# - >功能性F# - >惯性F#”的路径。 您的C#库功能越强,您的库在F#中的可用性就越大。功能风格有助于提高可组合性,并且更接近于惯用的F#代码。沿着这些方向,您可以:

  • 默认情况下拥抱不变性原则。如果您不知道以后是否需要更新字段/属性,请先将其标记为readonly
  • 遵循基于表达式和声明性编程风格。 LINQ操作就是很好的例子。
  • 以不可变的方式使用不可变集合或可变集合。使用introduction of C# immutable collections,它应该比以前更容易。

上图来自F# for fun and profitPorting from C# to F# series。他们非常有帮助;了解如何在F#中表达C#概念将提高您的库的可用性。

很难避免C#的面向对象功能。请记住,F#类型推断对这些功能不起作用。沿着保持对象层次结构简单的方法,您应该减少成员重载的数量。大量的成员重载很容易混淆F#类型检查器。此外,使用C#库分发一个瘦F#包装器并没有什么坏处。您需要做的一些事情是将一些方法转换为模块函数并创建Active Patterns以分解对象层次结构。