2009-07-31 13 views
6

In C# kann ichAllgemein Module in F #

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

kompilieren Das Ergebnis ist generisch und ist nicht instantiable.

Was ist der äquivalente F # -Code? module<'a> kompiliert nicht und type Foo<'a> ist instanziierbar.

Antwort

9

Die anderen Antworten haben bisher jeweils ein Teil des Bildes ...

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

groß ist. Unabhängig davon, was Reflector generiert, können Sie diese Klasse nicht innerhalb der F # -Assembly instanziieren (da der Konstruktor privat ist). Dies funktioniert also gut.

F # erlaubt auch statische Konstruktoren, die Syntax beinhaltet 'static let' und 'static do' Anweisungen in der Klasse (die analog funktionieren wie 'let' und 'do' als Teil des primären Konstruktors) Körper für Instanzen). Ein vollständiges Beispiel:

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

Liebe die // 'Trick wird das von jetzt an – ShuggyCoUk

+0

Hallo. Bitte vergib meine Unwissenheit, aber was ist der Trick? Ich starre auf den Code und es verhält sich genauso, mit oder ohne es. Vielen Dank. – user2916547

2

ich zuerst dachte, dass dies zu schließen wäre, was man wollte:

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

wie das Idiom pre Seine C# 2.0 von selbst instantiable nur durch Reflexion oder durch die Klasse zu sein (was würde hoffentlich nicht tun es).

dies ist jedoch kompiliert bis:

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

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

was bedeutet, dass andere Klassen innerhalb der f # Montage es instanziiert könnte. Der jemals informierte Brian hat jedoch darauf hingewiesen, dass der f # -Compiler trotz des zugrunde liegenden CLR-Typs diese private Einstellung respektiert, was bedeutet, dass die einzige Möglichkeit zur Instanziierung die Reflektion oder die Verwendung des Attributs InternalsVisibleTo ist.

Diese noch für Ihre Bedürfnisse akzeptabel sein kann ...

+0

Andere Klassen können es nicht instanziieren; Der Konstruktor ist für diesen F # -Typ "privat", soweit es F # betrifft. – Brian

+0

ah - so f # respektiert die private über die tatsächlichen .net CLR-Einschränkungen ... InternalsVisibleTo würde es aus der Tasche zu aC# Assembly noch lassen (nicht, dass ich darauf hinweise, dass dies ein Fehler ist, nur dass es möglich ist mit legalem nicht vertrauenswürdigem Code). Ich werde die Antwort cheers – ShuggyCoUk