Proprietà indicizzate
Nell'ambito della definizione di una classe astratta rispetto a dati ordinati, talvolta può essere utile fornire un accesso indicizzato a tali dati senza esporre l'implementazione sottostante. Viene effettuato con il membro Item
.
Sintassi
Sintassi per le espressioni:
// Looking up an indexed property
expr[idx]
/// Assign to an indexed property
expr[idx] <- elementExpr
Sintassi per le dichiarazioni dei membri:
// 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
Osservazioni:
I formati della sintassi precedente mostrano come definire le proprietà indicizzate con un metodo get
e set
, solo un metodo get
o solo un metodo set
. È anche possibile combinare la sintassi mostrata solo per GET e la sintassi mostrata solo per SET e produrre una proprietà che abbia sia GET sia SET. L'ultimo formato consente di inserire diversi modificatori e attributi di accessibilità nei metodi GET e SET.
Usando il nome Item
, il compilatore tratta la proprietà come proprietà indicizzata predefinita. Una proprietà indicizzata predefinita è una proprietà a cui poter accedere usando una sintassi di tipo matrice sull'istanza dell'oggetto. Ad esempio, se o
è un oggetto del tipo che definisce questa proprietà, la sintassi o[index]
viene usata per accedere alla proprietà.
La sintassi per accedere a una proprietà indicizzata non predefinita indica il nome della proprietà e l'indice tra parentesi, come un membro regolare. Ad esempio, se la proprietà su o
viene chiamata Ordinal
, si scrive o.Ordinal(index)
per accedervi.
A prescindere dalla forma in uso, si consiglia di usare la forma sottoposta a currying per il metodo impostato su una proprietà indicizzata. Per informazioni sulle funzioni sottoposte a currying, vedere Funzioni.
Prima di F# 6, la sintassi expr.[idx]
veniva usata per l'indicizzazione. Puoi attivare un avviso informativo facoltativo (/warnon:3366
o la proprietà <WarnOn>3366</WarnOn>
) per segnalare gli utilizzi della notazione expr.[idx]
.
Esempio
L'esempio di codice seguente illustra la definizione e l'uso di proprietà indicizzate predefinite e non predefinite con metodi GET e SET.
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 ""
Output
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
Proprietà indicizzate con più valori dell'indice
Le proprietà indicizzate possono avere più di un valore dell'indice. In tal caso, i valori vengono separati da virgole quando viene usata la proprietà. Il metodo SET in tale proprietà deve avere due argomenti sottoposti a currying, il primo dei quali è una tupla contenente le chiavi, mentre il secondo è il valore da impostare.
Il codice seguente dimostra l'uso di una proprietà indicizzata con più valori dell'indice.
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