2011-03-23 49 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的屬性)