是否可以在F#中创建静态成员索引属性? MSDN仅为实例成员显示它们,但是,我可以定义以下类:
type ObjWithStaticProperty =
static member StaticProperty
with get () = 3
and set (value:int) = ()
static member StaticPropertyIndexed1
with get (x:int) = 3
and set (x:int) (value:int) = ()
static member StaticPropertyIndexed2
with get (x:int,y:int) = 3
and set (x:int,y:int) (value:int) = ()
//Type signature given by FSI:
type ObjWithStaticProperty =
class
static member StaticProperty : int
static member StaticPropertyIndexed1 : x:int -> int with get
static member StaticPropertyIndexed2 : x:int * y:int -> int with get
static member StaticProperty : int with set
static member StaticPropertyIndexed1 : x:int -> int with set
static member StaticPropertyIndexed2 : x:int * y:int -> int with set
end
但是当我尝试使用一个时,我收到一个错误:
> ObjWithStaticProperty.StaticPropertyIndexed2.[1,2] <- 3;;
ObjWithStaticProperty.StaticPropertyIndexed2.[1,2] <- 3;;
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error FS1187: An indexer property must be given at least one argument
我尝试了一些不同的语法变体,但都没有。同样奇怪的是,当我将鼠标悬停在VS2010中的set
上以获取该类型中的一个定义时,我会获得有关ExtraTopLevelOperators.set
的信息。
答案 0 :(得分:5)
如果要恢复Type.Prop.[args]
表示法,则可以定义一个简单对象来表示具有Item
属性的可索引属性:
type IndexedProperty<'I, 'T>(getter, setter) =
member x.Item
with get (a:'I) : 'T = getter a
and set (a:'I) (v:'T) : unit = setter a v
type ObjWithStaticProperty =
static member StaticPropertyIndexed1 =
IndexedProperty((fun x -> 3), (fun x v -> ()))
ObjWithStaticProperty.StaticPropertyIndexed1.[0]
每次都会返回IndexedProperty
的新实例,因此最好将其缓存。无论如何,我认为这是一个非常好的技巧,你可以将一些额外的行为封装到属性类型中。
一个题外话:我认为对F#的一个优雅扩展就是拥有一等属性,就像它有一流的事件一样。 (例如,您可以创建仅使用一行代码自动支持INotifyPropertyChange
的属性)
答案 1 :(得分:4)
我相信您使用不同的语法(无论是实例还是静态)调用索引属性:
ObjWithStaticProperty.StaticPropertyIndexed2(1,2) <- 3
唯一的例外是,Item
实例上的x
属性可以通过x.[...]
调用(即省略Item
,括号为围绕参数使用。)