2009-07-31 11 views
6

C#, można opracowaćogólne moduły F #

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

Wynikiem jest ogólne i nie jest chwilowe.

Jaki jest równoważny kod F #? module<'a> nie kompiluje się, a type Foo<'a> jest natychmiastowy.

Odpowiedz

9

innych odpowiedzi do tej pory każdy ma część obrazu ...

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

jest wielki. Zignoruj ​​to, co generuje Reflector, nie możesz utworzyć instancji tej klasy z zestawu F # (ponieważ konstruktor jest prywatny), więc to działa dobrze.

F # dopuszcza również konstruktory statyczne, składnia ma zawierać instrukcje "static let" i "static do" w klasie (które działają analogicznie do tego, jak działają "let" i "do" jako część podstawowego konstruktora ciało dla instancji). Pełny przykład:

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

Uwielbiam // sztuczka zrobi to od teraz na – ShuggyCoUk

+0

Witam. Proszę wybaczyć moją niewiedzę, ale czym jest sztuczka? Wpatruję się w kod i zachowuję się tak samo, z lub bez niego. Dziękuję Ci. – user2916547

2

Myślałem na początku, że będzie to bliskie temu, co chciał:

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

Być jak sprzed idiom C# 2.0 jest chwilowe jedynie poprzez odbicie lub przez samą klasę (co mam nadzieję, że nie zrobi to).

jednak ten jest kompilowany do:

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

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

co oznacza, że ​​inne klasy F # w obrębie zespołu mógłby go instancję.

Jednak nigdy nie poinformowany Brian poinformował, że kompilator f # respektuje to prywatne ustawienie, pomimo leżącego u jego podstaw typu CLR, co oznacza, że ​​jedynym sposobem na utworzenie wystąpienia będzie odbicie lub użycie czegoś takiego jak atrybut InternalsVisibleTo.

To nadal może być do zaakceptowania dla potrzeb ...

+0

Inne klasy nie mogą utworzyć instancji; konstruktor jest "prywatny" dla tego typu F #, jeśli chodzi o F #. – Brian

+0

ah - tak f # respektuje prywatność ponad faktycznymi restrykcjami CLR .NET InternalsVisibleAby jednak wypuścić ją z torby do AC# mimo że nadal (nie żebym wskazał, to jest wada, tylko że jest to możliwe z legalnym niezaufanym kodem). Będę aktualizować odpowiedź na okrzyki – ShuggyCoUk