2009-07-31 4 views
6

In C#, posso compilaremoduli generici in F #

static class Foo<T> { /* static members that use T */ } 

Il risultato è generico e non è istanziabili.

Qual è il codice F # equivalente? module<'a> non viene compilato e type Foo<'a> è istantaneo.

risposta

9

Le altre risposte finora hanno ciascuna una parte del quadro ...

type Foo<'a> private() =   // ' 
    static member Blah (a:'a) = // ' 
     printfn "%A" a 

è grande. Ignora ciò che genera Reflector, non puoi istanziare questa classe dall'assembly F # (poiché il costruttore è privato), quindi funziona bene.

F # consente anche costruttori statici, la sintassi deve includere istruzioni 'static let' e 'static do' nella classe (che funzionano analogamente a come 'let' e 'do' funzionano come parte del costruttore principale corpo per istanze). Un esempio completo:

type Foo<'a> private() =    // ' 
    static let x = 0 
    static do printfn "Static constructor: %d" x 
    static member Blah (a:'a) =  // ' 
     printfn "%A" a 

//let r = new Foo<int>() // illegal 
printfn "Here we go!" 
Foo<int>.Blah 42 
Foo<string>.Blah "hi" 
+4

love the // 'trucco lo farà da ora in poi – ShuggyCoUk

+0

Ciao. Per favore perdona la mia ignoranza, ma qual è il trucco "//"? Sto fissando il codice e si comporta allo stesso modo, con o senza di esso. Grazie. – user2916547

2

ho pensato in un primo momento che questo sarebbe stato vicino a quello che si voleva:

type Foo<'a> private() = 
    static member Blah (a:'a) = 
     printfn "%A" a 

Essere come pre linguaggio C# 2.0 di essere istanziabile solo attraverso la riflessione o la classe stessa (che si spera non farebbe esso).

tuttavia questo viene compilato fino a:

[Serializable, CompilationMapping(SourceConstructFlags.ObjectType)] 
public class Foo<a> 
{ 
    internal Foo() {...} 

    public static void Blah(a a) {...} 
} 

il che implica che le altre classi all'interno del # assemblaggio f creare un'istanza di esso.

Tuttavia il sempre informato Brian ha indicato che il compilatore f # rispetta questa impostazione privata nonostante il tipo di CLR sottostante, il che significa che l'unico modo per creare un'istanza sarebbe tramite riflessione o utilizzando qualcosa come l'attributo InternalsVisibleTo.

Questo può ancora essere accettabile per le vostre esigenze ...

+0

Altre classi non possono istanziarlo; il costruttore è 'privato' per questo tipo di F # per quanto riguarda F #. – Brian

+0

ah - così f # rispetta il privato al di là delle attuali restrizioni CLR .net ... InternalsVisibleTo lo lascerebbe fuori dalla borsa per l'assemblaggio # ac ancora (non che sto indicando che questo è un difetto, solo che è possibile con codice legale non attendibile). Aggiornerò la risposta acclamazioni – ShuggyCoUk