7

例如,如果我在 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 = ...

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

然后我尝试用 替换modulenamespace每次我引入一些辅助函数时,我都必须用新名称创建一个新模块。有时我可以设法将所有辅助函数重新排列到 1 个模块中,但这会导致代码的可读性降低。

什么是更好的结构呢?

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

4

2 回答 2

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 = ()

F# 系列遵循类似的设计。您可以使用[<AutoOpen>][<RequireQualifiedAccess>]属性进一步控制如何从 F# 使用模块。

于 2013-01-22T17:02:03.733 回答
4

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

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

这需要做更多的工作,因为您需要使用特殊属性标记模块(以避免名称冲突),但它在 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
于 2013-01-22T17:02:18.137 回答