我只是想指出这个问题不是
的反面Best approach for designing F# libraries for use from both F# and C#
在这里,我不是要问如何设计一个用于两个世界的C#函数库。
我想了解良好做法,了解设计选择包含或避免以获得合理的妥协,使此库可用于F#
像(例如)的实践:
保持对象层次结构尽可能简单
避免改变对象的状态,但返回新的
等...
任何已经完成它的人都可以分享它的经验吗?
旁注
有趣的是,这个OSS项目IronJS。是的,它是用F#编写的,但是作者公开了两个专门的主持人IronJS.Hosting.FSharp
和IronJS.Hosting.CSharp
。
答案 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#库以获得更好的可用性。以下是您可能采取的路径:
我专注于“命令性C# - >功能性C# - >功能性F# - >惯性F#”的路径。 您的C#库功能越强,您的库在F#中的可用性就越大。功能风格有助于提高可组合性,并且更接近于惯用的F#代码。沿着这些方向,您可以:
readonly
。上图来自F# for fun and profit的Porting from C# to F# series。他们非常有帮助;了解如何在F#中表达C#概念将提高您的库的可用性。
很难避免C#的面向对象功能。请记住,F#类型推断对这些功能不起作用。沿着保持对象层次结构简单的方法,您应该减少成员重载的数量。大量的成员重载很容易混淆F#类型检查器。此外,使用C#库分发一个瘦F#包装器并没有什么坏处。您需要做的一些事情是将一些方法转换为模块函数并创建Active Patterns以分解对象层次结构。