Я не думаю, что вы можете сделать это ... на самом деле, вы не можете получить доступ к значениям let-привязки из других экземпляров:
type Foo() =
let x = 3
member this.Test(f:Foo) =
f.x // same error
В общем, если вам нужно получить доступ к такому значению за пределами экземпляра, к которому оно принадлежит, вам, вероятно, следует либо создать личное свойство для получения значения, либо использовать вместо него личное поле.
UPDATE
Это покрыто разделом 8.6.2 спецификации . В частности:
Привязки экземпляра «let» лексически ограничены (и, следовательно, неявно частными) для определяемого объекта.
Возможно, кто-то из команды F # ответит на вопрос, почему язык ведет себя так. Однако я могу подумать о нескольких возможных причинах:
- значения let-привязки могут даже не присутствовать в виде полей (например, опять из спецификации, привязка let будет представлена локальным для конструктора ", если значение не является синтаксической функцией, не является изменяемым и не используется в любой функции или члене ")
- Это, похоже, согласуется с поведением привязок let в других местах языка. Посмотрите примеры примерно эквивалентных определений классов и записей, которые я включил ниже (потому что я не могу правильно форматировать блоки кода в упорядоченном списке ...)
- Это обеспечивает более детальный уровень инкапсуляции, чем это возможно во многих других языках - привязки, которые являются локальными для определяемого объекта. Зачастую другие экземпляры не нуждаются в доступе к этим привязкам, и в этом случае желательно не показывать их.
- Если вы хотите что-то, что доступно другим экземплярам вашего класса (или из статических методов), есть простой способ сделать это - создать личное поле или свойство, которое имеет преимущество в явном выражении вашего намерения, что значение будет доступно снаружи экземпляра, в котором вы находитесь.
Как упоминалось ранее, вот примерно эквивалентное определение класса и метод для создания записи:
type MyClass(i:int) =
let j = i * i
member this.IsSameAs(other:MyClass) =
false // can't access other.j here
type myRecord = { isSameAs : myRecord -> bool }
let makeMyRecord(i:int) =
let j = i * i
{ isSameAs = (fun r -> false) } //obviously, no way to access r.j here
Поскольку конструкторы в F # концептуально похожи на любую другую функцию, которая возвращает экземпляр типа (например, они могут быть вызваны без использования new
), вызов MyClass 5
концептуально аналогичен вызову makeMyRecord 5
. В последнем случае мы явно не ожидаем, что существует какой-либо способ доступа к локальной привязке let для j
из другого экземпляра записи. Следовательно, в первом случае у нас также нет доступа к привязке.