Управление доступом к полям в типах F # - PullRequest
1 голос
/ 17 октября 2019

Я пишу доменную логику для одного из приложений, используя F #. Я хочу контролировать доступ к полям, определенным для типа в F #, чтобы я мог реализовать шаблон построителя и создать экземпляр типа управления.

Хотите сделать нечто подобное с do в шаблоне построителя в C # / Java.

Пожалуйста, предложите.

например, пусть Person = {Имя: строка Возраст: число Зарплата: строка}

Так что я хочу убедиться, что человеку всегда нужно указывать имя и возраст. Но зарплата должна быть необязательной. Инстанциация должна происходить по схеме строителя.

Ответы [ 3 ]

2 голосов
/ 17 октября 2019

Вы не можете сделать отдельные поля записи private или internal, но вы можете сделать все поля private или internal. Это скрывает все поля, поэтому вы должны выставить те, которые вы хотите сделать доступными в качестве участников. Вы также можете добавить статические методы для создания новых значений. Например:

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 }

Теперь вы не можете получить доступ к полям или создать запись напрямую, но вы можете использовать Create и WithSalary:

Person.Create("Joe", 60).WithSalary(10000)
1 голос
/ 17 октября 2019

Вы можете реализовать шаблон построителя с простыми функциями. Я не вижу смысла использовать объекты здесь:

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
1 голос
/ 17 октября 2019

Как отмечено в комментарии, кажется, что вы пытаетесь использовать объектно-ориентированные шаблоны без объектов, что вряд ли является хорошей идеей.

Если вы решите использовать типы 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
...