2015-09-06 5 views
7

Ich habe eine F # -Klasse, die von einer .NET-Klasse mit mehreren Konstruktoren abgeleitet ist. Um sie alle verfügbar zu machen, implementiere ich einen Typ ohne primären Konstruktor. Jetzt möchte ich ein statisches Feld hinzufügen. Wie initialisiere ich das statische Feld? Bedenken Sie:In F #, wie initialisiere ich statische Felder in einem Typ ohne primären Konstruktor?

type MyType = 
    inherit DotNetType 
    [<DefaultValue>] static val mutable private myStatic : int 
    new() = { inherit DotNetType() } 
    new (someArg:string) = { inherit DotNetType(someArg) } 

Nun, wie kann ich die „myStatic“ Feld in einer Art und Weise zu initialisieren, die genau einmal ausgeführt wird, wenn der Typ verwendet wird, und schon gar nicht, wenn der Typ nie verwendet? Im Wesentlichen brauche ich das Äquivalent eines C# statischen Konstruktorblocks.

+0

Würde, die Ihr Problem lösen: https://msdn.microsoft.com /de-de/library/dd483473.aspx? – MarcinJuraszek

+0

Nein, es wäre nicht, weil mein Typ keinen primären Konstruktor hat. Ein "static do" bringt mir diesen Fehler: "Statische Wertdefinitionen dürfen nur in Typen mit einem primären Konstruktor verwendet werden. Erwägen Sie, der Typdefinition Argumente hinzuzufügen, z. B. 'type X (args) = ...'." Danke für die Antwort, obwohl. –

Antwort

2

Siehe F# spec, Abschnitt 8.6.3 Weitere Objektkonstruktoren der Klassen:

For classes without a primary constructor, side effects can be performed after the initialization of the fields of the object by using the additional-constr-expr then stmt form.

Beispiel:

type MyType = 
    inherit DotNetType 
    [<DefaultValue>] static val mutable private myStatic : int 
    new() = { inherit DotNetType() } then MyType.myStatic <- 1 
    new (someArg:string) = { inherit DotNetType(someArg) } 
    static member Peek = MyType.myStatic 

MyType.Peek |> printfn "%d" // prints 0 
MyType() |> ignore 
MyType.Peek |> printfn "%d" // prints 1 
+0

Aber das führt die Logik einmal pro Aufruf an den Konstruktor, nicht einmal pro Initialisierung des Typs selbst. – kvb

+0

@ kvb Er führt den Code _after_ Initialisierung für jeden Aufruf des Konstruktors aus, während 'statische do'-Anweisungen von primären Konstruktoren beim Start ausgeführt werden, unabhängig von einem Aufruf eines Konstruktors. Daher emuliert keiner das Verhalten eines [C# statischen Konstruktors] (https://msdn.microsoft.com/en-us/library/k9x6w0hc%28v=vs.140%29.aspx), der vor der ersten Instanz ausgeführt wird erstellt. Die 'additional-constr-expr then stmt'-Form erlaubt es, zumindest etwas Kontrolle nahe zu kommen. – kaefer

Verwandte Themen