Поделиться через


Свойства (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

См. также

Ссылки

Методы (F#)

Основные понятия

Члены (F#)