Индексированные свойства

При определении класса, который абстрагирует упорядоченные данные, иногда может быть полезно предоставить индексированные доступ к этим данным без предоставления базовой реализации. Это делается с Item членом.

Синтаксис

Синтаксис для выражений:

// Looking up an indexed property
expr[idx]

/// Assign to an indexed property
expr[idx] <- elementExpr

Синтаксис для объявлений членов:

// Indexed property that can be read and written to
member self-identifier.Item
    with get(index-values) =
        get-member-body
    and set index-values values-to-set =
        set-member-body

// Indexed property can only be read
member self-identifier.Item
    with get(index-values) =
        get-member-body

// Indexed property that can only be set
member self-identifier.Item
    with set index-values values-to-set =
        set-member-body

Замечания

Формы предыдущего синтаксиса показывают, как определить индексированные свойства, имеющие как метод, так get и set метод, get только метод или set только метод. Можно также объединить синтаксис, показанный только для получения, и синтаксис, показанный только для набора, и создать свойство, которое имеет как get, так и set. Эта последняя форма позволяет поместить различные модификаторы специальных возможностей и атрибуты в методы get и set.

Используя имя Item, компилятор обрабатывает свойство как индексированное свойство по умолчанию. Индексированные свойства по умолчанию — это свойство , к которому можно получить доступ с помощью синтаксиса, подобного массиву, в экземпляре объекта. Например, если o является объектом типа, который определяет это свойство, синтаксис o[index] используется для доступа к свойству.

Синтаксис для доступа к индексированного свойства, отличного от по умолчанию, заключается в том, чтобы указать имя свойства и индекс в скобках, как и обычный элемент. Например, если вызывается Ordinalсвойствоo, записывается o.Ordinal(index) для доступа к нему.

Независимо от того, какая форма используется, всегда следует использовать курриированную форму для метода set в индексированного свойства. Сведения о курированных функциях см. в разделе "Функции".

До F# 6 синтаксис expr.[idx] использовался для индексирования. Вы можете активировать необязательное информационное предупреждение (/warnon:3566 или свойство <WarnOn>3566</WarnOn>), чтобы сообщить об использовании expr.[idx] нотации.

Пример

В следующем примере кода показано определение и использование свойств индексированных по умолчанию и не по умолчанию, имеющих методы получения и задания.

type NumberStrings() =
    let mutable ordinals =
        [| "one"
           "two"
           "three"
           "four"
           "five"
           "six"
           "seven"
           "eight"
           "nine"
           "ten" |]

    let mutable cardinals =
        [| "first"
           "second"
           "third"
           "fourth"
           "fifth"
           "sixth"
           "seventh"
           "eighth"
           "ninth"
           "tenth" |]

    member this.Item
        with get (index) = ordinals[index]
        and set index value = ordinals[index] <- value

    member this.Ordinal
        with get (index) = ordinals[index]
        and set index value = ordinals[index] <- value

    member this.Cardinal
        with get (index) = cardinals[index]
        and set index value = cardinals[index] <- value

let nstrs = new NumberStrings()
nstrs[0] <- "ONE"

for i in 0..9 do
    printf "%s " nstrs[i]

printfn ""

nstrs.Cardinal(5) <- "6th"

for i in 0..9 do
    printf "%s " (nstrs.Ordinal(i))
    printf "%s " (nstrs.Cardinal(i))

printfn ""

Выходные данные

ONE two three four five six seven eight nine ten
ONE first two second three third four fourth five fifth six 6th
seven seventh eight eighth nine ninth ten tenth

Индексированные свойства с несколькими значениями индекса

Индексированные свойства могут иметь несколько значений индекса. В этом случае значения разделяются запятыми при использовании свойства. Метод set в таком свойстве должен иметь два куриированных аргумента, первый из которых является кортежем, содержащим ключи, и второй из которых является значением для задания.

В следующем коде показано использование индексированного свойства с несколькими значениями индекса.

open System.Collections.Generic

/// Basic implementation of a sparse matrix based on a dictionary
type SparseMatrix() =
    let table = new Dictionary<(int * int), float>()
    member _.Item
        // Because the key is comprised of two values, 'get' has two index values
        with get(key1, key2) = table[(key1, key2)]

        // 'set' has two index values and a new value to place in the key's position
        and set (key1, key2) value = table[(key1, key2)] <- value

let sm = new SparseMatrix()
for i in 1..1000 do
    sm[i, i] <- float i * float i

См. также