Pourquoi ne puis-je pas avoir "public static const string S =" stuff "; dans ma classe?

321

Lorsque j'essaie de compiler ma classe, j'obtiens une erreur:

La constante 'NamespaceName.ClassName.CONST_NAME'ne peut pas être marquée comme statique.

à la ligne:

public static const string CONST_NAME = "blah";

Je pouvais faire ça tout le temps en Java. Qu'est-ce que je fais mal? Et pourquoi ça ne me laisse pas faire ça?

jjnguy
la source

Réponses:

583

Un constobjet est toujours static.

Joel Coehoorn
la source
2
const rend la variable constante et ne peut pas être modifiée.
Samuel
6
@jinguy: const signifie intrinsèquement statique - si vous avez un const, il est déjà statique, et statique n'a donc pas besoin d'être ni ne peut être spécifié.
John Rudy
8
@jjnguy: Pourquoi? readonly est en fait plus flexible que la version finale de Java pour les variables - vous pouvez le définir autant de fois que vous le souhaitez dans le constructeur, mais pas ailleurs. Cela peut être très pratique.
Jon Skeet
67
Les consts sont insérés au moment de la compilation et ne sont pas présents dans l'objet de type statique au moment de l'exécution. Les statiques ne sont pas alignées et vivent à l'intérieur de l'objet type. J'ajoute cela juste parce que personne n'a mentionné la différence ...
3
Ils sont toujours présents au moment de l'exécution - vous pouvez y accéder avec réflexion, par exemple (avec GetField).
Jon Skeet
32

Un membre const est considéré comme statique par le compilateur, tout comme impliquant une sémantique de valeur constante, ce qui signifie que les références à la constante peuvent être compilées dans le code utilisant comme valeur du membre constant, au lieu d'une référence au membre.

En d'autres termes, un membre const contenant la valeur 10 peut être compilé dans un code qui l'utilise comme numéro 10, au lieu d'une référence au membre const.

Ceci est différent d'un champ statique en lecture seule, qui sera toujours compilé comme référence au champ.

Remarque, ceci est pré-JIT. Lorsque le JIT'ter entre en jeu, il peut les compiler dans le code cible sous forme de valeurs.

Lasse V. Karlsen
la source
Point très important, que le code compilé présume que la valeur constante ne changera pas dans une future version.
PJTraill
6

C # constest exactement la même chose que Java final, sauf qu'il est absolument toujours static. À mon avis, il n'est pas vraiment nécessaire qu'une constvariable soit non static, mais si vous avez besoin d'accéder à une constvariable non static-ly, vous pouvez faire:

class MyClass
{    
    private const int myLowercase_Private_Const_Int = 0;
    public const int MyUppercase_Public_Const_Int = 0;

    /*        
      You can have the `private const int` lowercase 
      and the `public int` Uppercase:
    */
    public int MyLowercase_Private_Const_Int
    {
        get
        {
            return MyClass.myLowercase_Private_Const_Int;
        }
    }  

    /*
      Or you can have the `public const int` uppercase 
      and the `public int` slighly altered
      (i.e. an underscore preceding the name):
    */
    public int _MyUppercase_Public_Const_Int
    {
        get
        {
            return MyClass.MyUppercase_Public_Const_Int;
        }
    } 

    /*
      Or you can have the `public const int` uppercase 
      and get the `public int` with a 'Get' method:
    */
    public int Get_MyUppercase_Public_Const_Int()
    {
        return MyClass.MyUppercase_Public_Const_Int;
    }    
}

Eh bien, maintenant je réalise que cette question a été posée il y a 4 ans, mais depuis que j'ai mis environ 2 heures de travail, consistant à essayer toutes sortes de façons différentes de répondre et de formater le code, dans cette réponse, je la poste toujours. :)

Mais, pour mémoire, je me sens toujours un peu idiot.

Meowmaritus
la source
4
Pour autant que je sache, Java finalse comporte exactement comme C # readonly, et pas du tout comme const.
Ben Voigt
@jjnguy Merci pour la modification; Je ne sais pas vraiment pourquoi j'ai choisi cette formulation originale.
Meowmaritus
6

Depuis MSDN: http://msdn.microsoft.com/en-us/library/acdd6hb7.aspx

... De plus, alors qu'un champ const est une constante au moment de la compilation , le champ en lecture seule peut être utilisé pour les constantes d'exécution ...

Donc, utiliser statique dans les champs const, c'est comme essayer de rendre statique défini (avec #define) en C / C ++ ... Comme il est remplacé par sa valeur au moment de la compilation, bien sûr, il est lancé une fois pour toutes les instances (= statique) .

uriel
la source
2

const est similaire à static, nous pouvons accéder aux deux variables avec le nom de classe, mais diff est statique, les variables peuvent être modifiées et const ne peut pas.

soujanya
la source