2011-03-23 48 views
3

是否有可能在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的信息。

回答

4

我相信,你叫使用不同的语法索引属性(是否实例或静态):

ObjWithStaticProperty.StaticPropertyIndexed2(1,2) <- 3 

只有半的例外是,在一个实例xItem属性可以通过x.[...]被称为(即,Item被省略,括号用于参数)。

+0

因此'x。[...]'语法只对一个实例有效? – Stringer 2011-03-23 09:48:00

+1

@Stringer - 它比这更具体 - 它只对名为“Item”的实例属性有效。 – kvb 2011-03-23 15:32:50

+2

@Stringer实际上,对于由类型的System.Reflection.DefaultMemberAttribute命名的任何实例属性都是有效的。如果该类型未用该属性修饰,则默认为“Item”。例子:'[] type C()= member x.Foo with get i = i ;;让三= C()。[3] ;;' – phoog 2013-11-26 19:59:00

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的属性)