为什么不是';F#中是否有受保护的访问修饰符?

为什么不是';F#中是否有受保护的访问修饰符?,f#,F#,有没有更好的方法在F#中建模数据以避免需要它?在F#中,protected修饰符可能会有很大的问题,因为您经常需要从lambda表达式调用成员。但是,当您这样做时,您不再从类中访问该方法。在使用C#中声明的受保护成员时,这也会导致混淆(请参见示例)。如果您可以声明一个受保护的成员,那么下面的代码可能会令人惊讶: type Base() = protected member x.Test(a) = a > 10 type Inherited() = inherit Base()

有没有更好的方法在F#中建模数据以避免需要它?

在F#中,
protected
修饰符可能会有很大的问题,因为您经常需要从lambda表达式调用成员。但是,当您这样做时,您不再从类中访问该方法。在使用C#中声明的受保护成员时,这也会导致混淆(请参见示例)。如果您可以声明一个
受保护的
成员,那么下面的代码可能会令人惊讶:

type Base() = 
  protected member x.Test(a) = a > 10

type Inherited() = 
  inherit Base()
  member x.Filter(list) =
    list |> List.filter (fun a -> x.Test(a))
此代码不起作用,因为您正在从lambda函数调用
Test
(该函数与
Test
的当前实例不同),因此代码不起作用。我认为这是不支持F#中的
protected
修饰符的主要原因


在F#中,使用实现继承(即从基类继承)的频率通常比在C#中要低得多,因此不需要像在C#中那样频繁地使用
受保护的
。相反,通常更倾向于使用接口(在面向对象的F#代码中)和高阶函数(在功能代码中)。但是,一般来说,很难说如何避免需要
保护
(除了通过避免实现继承)。您是否有一些具体的例子激发了您的问题?

关于F#是否能够更好地建模数据,签名文件允许比C#中的内部
更细粒度的可见性决策,这通常是非常好的。更多解释请参见Brian的评论。这与对
受保护的
的支持(或缺乏)无关。

这是事实,但它是编译器的一个实现工件。类似F#的.NET语言无法生成嵌套类来容纳闭包并具有预期的语义,这并不是根本原因。请参阅Eric Lippert()的这篇博客文章,讨论类似问题如何导致C#编译器以前发出无法验证的代码,尽管在C#4中,代码生成方法已经改变,以解决这个问题。@Tomas-我同意你的评论的后半部分:我不记得在使用F#时是否丢失了
protected
成员。至于你评论的前半部分,我认为这和公开一个公共成员包装一个受保护的成员没有什么不同。C#的方法对我来说似乎非常直观,我没有看到任何抱怨/困惑。这是F#伙计们对C#伙计们没有任何同情心的地方之一。当然它是可以实现的,但正如在c#中一样,F#语言达到了一个特定的阶段,作者(主要贡献者)不想添加任何内容,即使它明显缺失。另一个例子:F#中的类型推断很酷,但不完整,尽管你可以实现巧妙的破解,但你不能简单而明确地做到:重载模块运算符或模块函数,使用unicode字符作为自定义运算符。确切地说@Liviu当我在twitter上问到这一点时,我得到的答案是“虽然F#支持面向对象,但它是以一种固执己见的方式实现的“。我认为这更接近F#不支持定义受保护成员的真正原因:不编写大量面向对象代码的人认为它不重要。不幸的是,如果没有对受保护F#的支持,在.NET.link中就不能被视为一等公民dead@Maslow-谢谢你指出这一点;我已经更新了链接,我认为这是原始帖子的镜像。