2009-07-31 10 views
6

En C#, I puede compilarmódulos genéricos en F #

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

El resultado es genérico y no es instanciable.

¿Cuál es el código F # equivalente? module<'a> no compila, y type Foo<'a> es instanciable.

Respuesta

9

Las otras respuestas hasta el momento tienen cada uno una parte del cuadro ...

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

es grande. Ignore lo que genera Reflector, no puede instanciar esta clase desde el ensamblado F # (ya que el constructor es privado), así que esto funciona bien.

F # permite también constructores estáticos, la sintaxis debe incluir sentencias 'static let' y 'static do' en la clase (que funcionan análogamente a cómo 'let' y 'do' funcionan como parte del constructor primario cuerpo por instancias). Un ejemplo 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

me encanta el // truco que hará que a partir de ahora – ShuggyCoUk

+0

Hola. Por favor, perdona mi ignorancia, pero ¿cuál es el truco '// ''? Estoy mirando el código y se comporta igual, con o sin él. Gracias. – user2916547

2

Al principio pensé que esto sería cerca de lo que quería:

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

Ser como el pre lenguaje C# 2.0 de ser instanciable sólo a través de la reflexión o de la clase en sí (que esperemos que no lo haría eso).

sin embargo, esto se compila a:

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

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

lo que implica que otras clases dentro del ensamblaje # F podría crear instancias de ella.

Sin embargo, el siempre informado Brian ha indicado que el compilador f # respeta esta configuración privada a pesar del tipo CLR subyacente, lo que significa que la única forma de crear instancias sería a través de la reflexión o mediante el uso del atributo InternalsVisibleTo.

Esto todavía puede ser aceptable para sus necesidades ...

+0

Otras clases no pueden crear instancias de ella; el constructor es 'privado' para este tipo F # en lo que se refiere a F #. – Brian

+0

ah - así f # respeta el privado por encima de las restricciones actuales de .NET CLR ... InternalsVisibleTo todavía lo dejó fuera de la bolsa para ensamblar aC# (no es que esté indicando que esto es un defecto, solo que es posible con código legal que no es de confianza). Voy a actualizar la respuesta vitorea – ShuggyCoUk