如何向C#和F#公开尽可能友好的类型?

col*_*ang 7 f#

例如,如果我在F#中编写了一个模块

module Lib

type A =
    member this.x1 x = ...

let helpa x = ...
let helpb x = ...

type B =
    member this.y1 x = ...

let helpc x = ...

typeA with
    member this.x2 x = ...
typeB with
    member this.y2 x = ...
Run Code Online (Sandbox Code Playgroud)

它在F#中运行良好open Lib,但是,如果我想在C#中使用它(我只对类型和成员函数感兴趣Lib),每次我创建一个我必须的类型new Lib.A(...).它变得相当烦人,没有办法省略模块名称.调用静态方法Lib.A.C()就更麻烦了.

然后,我尝试更换modulenamespace,每个我介绍了一些辅助功能的时间我要创建一个新名称的新模块.偶尔我可以设法将所有辅助函数重新排列到1个模块中,但这会导致代码不太可读.

什么是更好的结构?

希望我拥有:Using * = Lib.*对于C#.

Dan*_*iel 7

F#在这里提供了比C#更多的灵活性,所以我会以标准方式将它暴露给C#,即将类型包含在命名空间中.我认为,像这样的东西提供了两全其美:

namespace Lib

type A =
    member this.x1 x = ()

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module A =
  let helpa x = ()
  let helpb x = ()

type B =
    member this.y1 x = ()

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module B =
  let helpb x = ()

type A with
    member this.x2 x = ()
type B with
    member this.y2 x = ()
Run Code Online (Sandbox Code Playgroud)

F#系列遵循类似的设计.您可以使用[<AutoOpen>][<RequireQualifiedAccess>]属性进一步控制F#中模块的使用方式.


Tom*_*cek 4

我认为您已经在答案中提到了最佳选择 -namespace在顶部使用声明定义文件(这样,您可以只using Lib用 C# 编写),然后将所有辅助函数放入模块中。

与某种类型(例如,与A)明确关联的辅助函数可以放入名为 的模块中A(类似于List模块中与该类型关联的F# 函数List<'T>)。

这需要更多工作,因为您需要使用特殊属性来标记模块(以避免名称冲突),但从 F# 和 C# 中使用它都会很容易(而且我认为良好的使用比保存一个更重要)构建库时击键次数很少):

namespace Lib

// Declaration of the 'A' type and helper functions in 'A' module 
type A() =
  member this.x1 x = 10

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module A = 
  let helpa (x:A) = x.x1
  let helpb (x:A) = x.x1

// Declaration of the 'B' type and helper functions in 'B' module 
type B() =
  member this.y1 x = 10

[<CompilationRepresentation(CompilationRepresentationFlags.ModuleSuffix)>]
module B = 
  let helpc (x:B) = x.y1

// Member augmentations for easy use from C#
type A with
    member this.x2 x = A.helpa this
type B with
    member this.y2 x = B.helpc this
Run Code Online (Sandbox Code Playgroud)