是否可以将记录字段设为私有?或者使记录成员私密?

col*_*ang 7 f#

我想坚持record,不想回去object.所以我想知道是否有可能成为field一个record private?或做出private memberrecord.其他concrete types诸如此类的discriminated union呢?

或者,此要求是否违反了语言规范?

Joh*_*lds 12

不,单个字段不可能是私有的:http://msdn.microsoft.com/en-us/library/dd233184

但是,您可以将所有字段设为私有,并通过属性公开所选字段.请注意,您需要一个Create-function才能创建记录实例,因为它的'字段是私有的:

type MyRec = 
    private
        { a : int
          b : int }
    member x.A = x.a
    member private x.Both = x.a + x.b  // Members can be private
    static member CreateMyRec(a, b) = { a = a; b = b }
Run Code Online (Sandbox Code Playgroud)

成员可以是私人的,就像MyRec.Both上面的财产一样.

编辑:以上使得字段 MyRec定义的模块是私有的,而不是MyRec的私有.当F#记录的字段被声明为私有时,请参阅Daniel对奇怪的可访问性范围的回答.

  • 是的,这很奇怪,并且没有记录在 MS 语言参考中。当我看到错误消息“记录字段不允许使用辅助功能修饰符”时,我偶然发现了它。使用“type R = internal ...”或“type R = private ...”来提供对整个表示的可访问性。 (2认同)
  • 我不知道MSDN,但它在规范中.请参阅[本节]中的表格(http://research.microsoft.com/en-us/um/cambridge/projects/fsharp/manual/spec.html#_Toc321997217). (2认同)

Tom*_*cek 12

此要求的问题是记录的语言功能要求属性是公共的.例如,如果你有一个记录r类型R与性质NameAge
{ r with Age = 20 },编译器开启到这一点new R(r.Name, 20).

我们的想法是with复制所有属性(不包括您想要更改的属性),因此它需要能够访问它们.为此,编译器实际上可以为每种可能的with用途生成方法,但这可能会生成许多方法.

你更喜欢唱片的原因是什么?它们有两个不错的功能 - with关键字(private无论如何都会失去成员)和结构相等(当它们具有相同的值时,两个实例是相同的).除此之外,如果你想隐藏一些字段,类似乎更容易使用.

这是一个简单的例子(它没有实现strucural相等):

type R(name:string, age:int) = 
  member x.Name = name
  member x.WithAge(newAge) = R(name, newAge)
Run Code Online (Sandbox Code Playgroud)

使用带private字段的记录似乎很好 - 尽管在实现文件中使用公共字段和为所有外部用户隐藏字段的F#签名文件可能更有意义.这样,您可以使用with实现中的功能,但仍然隐藏类型.