控制对F#类型字段的访问

时间:2019-10-17 09:46:10

标签: f# f#-interactive c#-to-f# f#-3.0

我正在使用F#为其中一个应用程序编写域逻辑。我想控制对F#中为类型定义的字段的访问,以便可以实现构建器模式和控制类型实例化。

想与C#/ Java中的构建器模式做类似的事情。

请提出建议。

例如 让Person = {     名称:字符串     年龄:人数     工资:字符串 }

因此,我想确保应该始终使用Name和Age实例化该人。但是薪水应该是可选的。实例化应该以构建器模式进行。

3 个答案:

答案 0 :(得分:2)

您不能创建单个记录字段privateinternal,但是可以创建所有字段privateinternal。这将隐藏所有字段,因此您必须公开要使其成为成员可访问的那些字段。您还可以添加静态方法来创建新值。例如:

type Person = 
  private { 
    name : string
    age : int 
    salary : int option }
  member x.Name = x.name
  member x.Age = x.age
  member x.Salary = x.salary

  static member Create(name:string, age:int) = 
    { name = name; age = age; salary = None }
  member x.WithSalary(s) =
    { x with salary = Some s }

现在您无法访问字段或直接创建记录,但是可以使用CreateWithSalary

Person.Create("Joe", 60).WithSalary(10000)

答案 1 :(得分:1)

正如评论中指出的那样,似乎您正在尝试使用没有对象的面向对象模式,这不是一个好主意。

如果您决定使用F#类型,则可以这样做:

type Employee = {
    name: string
    age: int
    salary: int option
}

let person1 = {
    name = "Mike",
    age = 42,
    salary = Some 4200
}
let person2 = {
    name = "Sue",
    age = 37,
    salary = None
}

省略名称或年龄会给您带来编译时错误,就像使用person1或person2一样,而无需检查工资是否存在。

要使用私有数据实施类似于构建器模式的操作,请执行以下操作:

type Employee = private {
    name: string
    age: int
    salary: int option
}

let name employee = employee.name
let employee name age = { name = name; age = age; salary = None }
let withSalary salary employee = { employee with salary = Some salary }

let mike = employee "Mike" 42 |> withSalary 4200

mike.name  //return name of this employee

答案 2 :(得分:1)

您可以使用简单的函数来实现构建器模式。我没有理由在这里使用对象:

type person =
  private {
    name: string
    age: int
    salary: int option
  }

let name person = person.name
let age person = person.age
let salary person = person.salary

let create name age = 
  { name = name; age = age; salary = None }

let withSalary salary person =
   { person with salary = Some salary }

create "Joe" 60
  |> withSalary 10000
  |> name