2010-03-08 9 views
17

En C# se puede definir una constante de miembro tipo como este:¿Cómo se define la constante de miembro de tipo en F #?

class Foo { public const int Bar = 600; } 

La IL se parece a esto.

.field public static literal int32 Bar = int32(600) 

¿Cómo puedo hacer lo mismo dentro de Visual F #/FSharp?

yo probamos este fue en vano:

[<Sealed>] 
type Foo() = 

    [<Literal>] 
    let Bar = 600 
+0

Hice esta pregunta - http://stackoverflow.com/questions/1834923/f-public-literal - y Chris Smith indicó que no es posible. – Daniel

Respuesta

0

No estoy seguro de que esto es posible. De hecho, ni siquiera creo que pueda crear campos públicos inmutables, sin mencionar las constantes.

+0

Creo que puede crear campos públicos inmutables usando la declaración 'val' y la inicialización explícita en el constructor escrito usando' new() ', pero eso no funcionaría para las constantes, porque los campos' val' se inicializan en el constructor. –

+0

@Tomas: creo que encontrará que su sugerencia realmente da como resultado una propiedad que se define, en lugar de un campo. Sin embargo, usar un 'val mutable' resulta en un campo mutable. – kvb

+0

Tienes razón. public 'val' da como resultado una propiedad con un campo privado (la motivación es prohibir que los posibles usuarios de C# de la clase modifiquen un campo que debería ser inmutable). –

18

Hice un par de experimentos con el compilador F # y aquí hay algunas de mis observaciones. Si desea crear IL literal, debe colocar el valor marcado como Literal dentro de un módulo. Por ejemplo así:

module Constants = 
    [<Literal>] 
    let Num = 1 

Como nota lateral, hice una búsqueda rápida a través del # especificación F y parece que literales pueden ser muy útiles para la coincidencia de patrones, porque se puede utilizar como un patrón (como se siempre y cuando comienzan con una letra mayúscula):

open Constants 
match 1 with 
| Num -> "1" 
| _ -> "other" 

Ahora, la pregunta es, ¿por qué Literal no se comporta como se puede esperar cuando se coloca dentro de una declaración de tipo. Creo que la razón es que la declaración let dentro de una declaración de tipo F # no puede ser pública y solo será visible dentro de la clase/tipo. Creo que tanto C# como F # incorporan valores literales cuando los usas y esto también se hace dentro de las declaraciones de tipo. Sin embargo, dado que el literal no puede ser público, no hay motivo para generar el campo IL literal, porque nadie podría acceder a él.

+0

En C# los literales estarán subrayados en el bytecode, pero el campo const aún estará allí para que se usen otros tipos. – zproxy

+0

Sí - en F # el 'campo' se generará si el literal es público (por ejemplo, en un módulo) y puede ser utilizado por alguien; si solo es visible dentro de la clase, no tiene sentido generar el bytecode porque otros tipos no pueden usarlo de todos modos. –

Cuestiones relacionadas