索引属性

定义一个对有序数据进行抽象的类时,在不公开基础实现的情况下提供对该数据的索引访问有时会很有帮助。 这通过 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

注解

上述语法的形式显示了如何定义同时具有 getset 方法、仅具有 get 方法或仅具有 set 方法的索引属性。 还可以将仅用于 get 的语法与仅用于 set 的语法结合起来,并生成一个同时具有 get 和 set 的属性。 使用后一种形式可以对 get 和 set 方法添加不同的可访问性修饰符和特性。

通过使用名称 Item,编译器会将该属性视为默认索引属性。 可以通过对对象实例使用类似数组的语法来访问默认索引属性。 例如,如果 o 是定义此属性的类型的对象,则使用语法 o[index] 访问该属性。

用于访问非默认索引属性的语法是在括号中提供属性名称和索引,就像常规成员一样。 例如,如果 o 上的属性称为 Ordinal,则可编写 o.Ordinal(index) 来访问它。

无论你使用哪种形式,都应该始终对索引属性的 set 方法使用扩充形式。 有关扩充函数的信息,请参阅函数

在 F# 6 之前,语法 expr.[idx] 用于编制索引。 可以激活可选的信息警告(/warnon:3566 或属性 <WarnOn>3566</WarnOn>)来报告 expr.[idx] 表示法的使用。

示例

以下代码示例说明了具有 get 和 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 ""

输出

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

另请参阅