【问题标题】:F# Friend function/classF# 朋友函数/类
【发布时间】:2011-03-13 03:58:58
【问题描述】:

是否可以在 F# 中实现友元函数和友元类(如在 c++ 中)?

更新: 由于f#中没有友元函数/类,而且friend甚至不是未来扩展的保留关键字,我想知道F#中的友元机制是否有任何问题让开发人员决定不实现它? (such as in "protected" access modifier)。

建议 1:Brian,签名文件 - 我认为这件事不能正常工作。如果你有一个评估 B.X 的闭包(例如 A 中的 lambda 表达式,它是与 A 的实例不同的对象),它将不起作用

建议 2:Massif (+Mitya0),InternalsVisibleTo - 我不清楚,你是在第二节课上写这个还是把这个课暴露给整个程序集?

【问题讨论】:

  • 您是指 C++ 中的“朋友”还是 VB.NET 中的“朋友”?

标签: f# oop friend


【解决方案1】:

请注意,您可以使用签名文件来模仿朋友。

如果你想让A成为B的朋友,那么A可以访问B的内部而其他人看不到,你可以这样做例如

// File1.fs
type B() =
    let x = 42  // private field
    member this.X = x // public getter

type A() =
    member this.PeekInto(b : B) =
        b.X

但也有

// File1.fsi
type B = 
    new : unit -> B
    // do not expose X in the signature

type A = 
    new : unit -> A
    PeekInto : B -> int

现在A的实现可以看到B.X,但是程序的续集看不到B.X

签名文件非常适合创建任意封装边界。

【讨论】:

  • 我也是 - 签名文件是该语言最令人敬畏的功能之一,似乎没人知道(请参阅stackoverflow.com/questions/181613/hidden-features-of-f/…
  • 是的 - 不幸的是,签名强加的可见性边界目前与文件边界严格重合
  • @Mitya,是的,给人们一个有用的新功能,他们所做的只是抱怨它不够灵活。 :)
  • fsi 文件不是新文件 - 它是 OCaml 的模块和模块签名的精简版本。
【解决方案2】:

正如米蒂亚指出的那样。只需在要查看受保护成员的类或整个程序集上使用 InternalsVisibleTo 属性。 (我一直这样做是为了进行单元测试)。

[<assembly:System.Runtime.CompilerServices.InternalsVisibleTo("UnitTestModule")>]

工作是一种享受。

【讨论】:

    【解决方案3】:

    存在于 C++ 中的朋友的概念并不完全转换为 F#,但您可以使用 internal 可访问性修饰符来允许访问同一 .NET 程序集中的所有类。这可能就是您正在寻找的。​​p>

    【讨论】:

    • internal 是一种钝器,请小心使用。
    • internal 只有在你的程序集很大时才会钝化。
    • @Mitya,是的,不幸的是,internal 强加的可见性边界与程序集边界严格重合。 :P
    • @Brian:我同意这一点。
    【解决方案4】:

    从我看到的文档来看,有一个 friend notion in C#,,但相同的文档表明 F# 没有这种能力。

    【讨论】:

    • 您引用的文档中的所有内容都适用于 F#,包括 InternalsVisibleTo 属性
    猜你喜欢
    • 2021-08-16
    • 2015-09-29
    • 2016-11-26
    • 2013-07-30
    • 2017-09-11
    • 1970-01-01
    • 2013-03-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多