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

时间:2012-09-12 13:29:02

标签: f#

我想坚持使用record,并且不想回到object。所以我想知道是否有可能field成为record private?或制作private member record。那么concrete types等其他discriminated union呢?

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

3 个答案:

答案 0 :(得分:12)

此要求的问题是记录的语言功能要求属性是公共的。例如,如果您的r类型的记录R具有属性NameAge并且写入了 { r with Age = 20 },编译器将其转换为new R(r.Name, 20)

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

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

这是一个简单的例子(不实现结构相等):

type R(name:string, age:int) = 
  member x.Name = name
  member x.WithAge(newAge) = R(name, newAge)

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

答案 1 :(得分:11)

不,单个字段不可能是私有的: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 }

成员可以是私人的,就像上面的MyRec.Both属性一样。

编辑:上面的内容隐藏了MyRec定义的模块字段,而不是MyRec的私有字段。请参阅Daniel对Weird accessibility scopes when F# record's fields are declared private的回答。

答案 2 :(得分:1)

我不认为这是可能的。 MSDN说:

  

记录字段与类的不同之处在于它们自动   作为属性公开,它们用于创建和复制   的记录。记录结构也与班级建设不同。   在记录类型中,您无法定义构造函数。

“自动曝光”是回答您问题的关键。有三个原因你不想创建一个新类型?