Свойства (F#)
Свойства — это члены, представляющие собой значения, связанные с объектом.
// Property that has both get and set defined.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with [accessibility-modifier] get() =
get-function-body
and [accessibility-modifier] set parameter =
set-function-body
// Alternative syntax for a property that has get and set.
[ attributes-for-get ]
[ static ] member [accessibility-modifier-for-get] [self-identifier.]PropertyName =
get-function-body
[ attributes-for-set ]
[ static ] member [accessibility-modifier-for-set] [self-identifier.]PropertyName
with set parameter =
set-function-body
// Property that has get only.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName =
get-function-body
// Alternative syntax for property that has get only.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with get() =
get-function-body
// Property that has set only.
[ attributes ]
[ static ] member [accessibility-modifier] [self-identifier.]PropertyName
with set parameter =
set-function-body
Заметки
В объектно-ориентированном программировании свойства соответствуют отношению "имеет", представляя собой данные, связанные с экземплярами объекта или — в случае статических свойств — с типом.
Свойства объявляются с помощью ключевого слова member, значения собственного идентификатора, представляющего текущий экземпляр, и имени свойства. За этим декларативным синтаксисом следует синтаксис, определяющий методы get и set, также называемые методами доступа. Различные показанные формы синтаксиса используются для свойств, доступных для чтения и на запись, только для чтения и только на запись. Для свойств, доступных только для чтения, определяется только метод get; для свойств, доступных только на запись, определяется только метод set. Обратите внимание, что, когда свойство имеет и метод доступа get, и метод доступа set, альтернативный синтаксис позволяет указать атрибуты и модификаторы доступности, разные для каждого из методов доступа, как показано в следующем коде.
// A read-only property.
member this.MyReadOnlyProperty = myInternalValue
// A write-only property.
member this.MyWriteOnlyProperty with set (value) = myInternalValue <- value
// A read-write property.
member this.MyReadWriteProperty
with get () = myInternalValue
and set (value) = myInternalValue <- value
Закрытые значения, в которых содержатся данные для свойств, называются резервными хранилищами. В отличие от других языков, F# не предусматривает механизма для создания неявного резервного хранилища для свойства; резервные хранилища нужно определять явно, обычно с помощью изменяемой привязки let, как показано ниже.
type MyClass(x : string) =
let mutable myInternalValue = x
member this.MyProperty
with get() = myInternalValue
and set(value) = myInternalValue <- value
В случае доступных для чтения и на запись свойств, имеющих и метод get, и метод set, методы get и set могут быть определены в обратном порядке. Другой вариант — вместо использования комбинированного синтаксиса можно записать синтаксис, показанный для случая "только метод get" и синтаксис, показанный для случая "только метод set". В этом случае будет проще закомментировать отдельно метод get или метод set, если это понадобится. Такая альтернатива использованию комбинированного синтаксиса показана в следующем коде.
member this.MyReadWriteProperty with get () = myInternalValue
member this.MyReadWriteProperty with set (value) = myInternalValue <- value
Свойства могут быть членами классов, структур, размеченных объединений, записей, интерфейсов и расширений типов, а также могут определяться в выражениях объектов.
К свойствам можно применять атрибуты. Чтобы применить атрибут к свойству, запишите атрибут на отдельной строке перед свойством. Дополнительные сведения см. в разделе Атрибуты (F#).
По умолчанию свойства являются открытыми. К свойствам также можно применять модификаторы доступности. Чтобы применить модификатор доступности, добавьте его непосредственно перед именем свойства, если он должен применяться и к методу get, и к методу set; если уровни доступа для этих методов должны быть разными, добавляйте модификатор перед ключевыми словами get и set. Можно использовать следующий accessibility-modifier: public, private или internal. Дополнительные сведения см. в разделе Управление доступом (F#).
Реализации свойств выполняются при каждом обращении к свойству.
Статические свойства и свойства экземпляра
Свойства могут быть статическими или свойствами экземпляра. Статические свойства могут вызываться без экземпляра и используются для значений, связанных с типом, а не с отдельными объектами. В случае статических свойств собственный идентификатор опускается. Для свойств экземпляров собственный идентификатор необходим.
Следующее определение статического свойства основывается на сценарии, в котором имеется статическое поле myStaticValue, представляющее собой резервное хранилище для свойства.
static member MyStaticProperty
with get() = myStaticValue
and set(value) = myStaticValue <- value
Свойства также могут иметь вид массивов; в этом случае они называются индексированными свойствами. Дополнительные сведения см. в разделе Индексированные свойства (F#).
Аннотация типа для свойств
Во многих случаях компилятор располагает достаточной информацией для вывода типа свойства из типа резервного хранилища, однако можно задать тип явно, добавив аннотацию типа.
// To apply a type annotation to a property that does not have an explicit
// get or set, apply the type annotation directly to the property.
member this.MyProperty1 : int = myInternalValue
// If there is a get or set, apply the type annotation to the get or set method.
member this.MyProperty2 with get() : int = myInternalValue
Использование методов доступа set свойств
Задавать свойства, предоставляющие методы доступа set, можно с помощью оператора <-.
// Assume that the constructor argument sets the initial value of the
// internal backing store.
let mutable myObject = new MyType(10)
myObject.MyProperty <- 20
printfn "%d" (myObject.MyProperty)
В результате получается 20.
Абстрактные свойства
Свойства могут быть абстрактными. Как и в случае с методами, термин абстрактный просто означает, что со свойством связана виртуальная ячейка отправки. Абстрактные свойства могут быть истинно абстрактными, т. е. не иметь определения в этом же классе. Содержащий такое свойство класс является, следовательно, абстрактным классом. Другой вариант — под абстрактностью может просто пониматься, что свойство является виртуальным; в этом случае определение должно присутствовать в этом же классе. Обратите внимание, что абстрактные свойства не должны быть закрытыми и, если один метод доступа является абстрактным, второй также должен быть абстрактным. Дополнительные сведения об абстрактных классах см. в разделе Абстрактные классы (F#).
// Abstract property in abstract class.
// The property is an int type that has a get and
// set method
[<AbstractClass>]
type AbstractBase() =
abstract Property1 : int with get, set
// Implementation of the abstract property
type Derived1() =
inherit AbstractBase()
let mutable value = 10
override this.Property1 with get() = value and set(v : int) = value <- v
// A type with a "virtual" property.
type Base1() =
let mutable value = 10
abstract Property1 : int with get, set
default this.Property1 with get() = value and set(v : int) = value <- v
// A derived type that overrides the virtual property
type Derived2() =
inherit Base1()
let mutable value2 = 11
override this.Property1 with get() = value2 and set(v) = value2 <- v