28 votes

Pourquoi cela compilerait-il?

J'ai créé un "const" pour une valeur précédemment explicitement indiquée plusieurs fois dans mon code:

 private static readonly int QUARTER_HOUR_COUNT = 96;
 

Lorsque j'ai effectué une recherche et remplacement de 96 pour QUARTER_HOUR_COUNT, j'ai par inadvertance également remplacé la déclaration, elle est donc devenue:

 private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
 

... mais il a compilé. Je pense que cela interdirait cela. Pourquoi a-t-il été accepté par le compilateur comme une déclaration valide?

23voto

Jon Skeet Points 692016

Je pense que ce serait interdit. Pourquoi était-il accepté par le compilateur comme une déclaration valide?

Sans doute parce que la spécification du langage le permet. Avez-vous une règle spécifique dans la spécification du langage qui, pensez-vous l'interdit?

Si votre question est "pourquoi ne pas le langage de spécification de l'interdire" - je suppose que c'est parce que c'est probablement assez dur pour s'assurer que vous seulement interdire les choses que vous voulez vraiment interdire, alors qu'en fait interdire toutes ces choses.

On pourrait dire que pour le simple cas de cession directement à lui-même, il serait bon d'avoir un cas spécial dans la langue spec, mais il faudrait introduire de la complexité dans la langue pour relativement peu d'avantages.

Notez que même si vous n'obtenez pas une erreur, je préfère attendre de vous que vous obtenez un avertissement - quelque chose comme cela:

Test.cs(3,33): avertissement CS1717: Affectation à la même variable; avez-vous l'intention de céder quelque chose d'autre?

Notez également que si vous en faites une const au lieu de seulement un static readonly variable, alors vous ne obtenez une erreur de compilation:

Test.cs(3,23): erreur CS0110: L'évaluation de la valeur de la constante pour le Programme.QUARTER_HOUR_COUNT' implique une définition circulaire

Notez également qu'en .NET conventions de nommage, ce devrait être appelés QuarterHourCount, plutôt que d'avoir un SHOUTY_NAME.

6voto

Anirudha Points 21931

Le code IL généré par le code est le suivant:

  IL_0007:  ldsfld     int32 Example.Quat::QUARTER_HOUR_COUNT//Load the value of a static field on the stack
 IL_000c:  stsfld     int32 Example.Quat::QUARTER_HOUR_COUNT// Store the value from the stack in the static field
 

Étant donné que la valeur par défaut de QUARTER_HOUR_COUNT est 0, le 0 est affecté à QUARTER_HOUR_COUNT

5voto

Geek Points 2250

Parce que la variable a été initialisée à 0 puis définie sur elle-même.

Ma conjecture serait qu'il ferait un nouveau Int () avant de se mettre à lui-même qui l'initialiserait à zéro.

4voto

Phillip Schmidt Points 5600

Parce que le compilateur rompra cette ligne:

 private static readonly int QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
 

Fondamentalement dans l'équivalent IL de:

 private static readonly int QUARTER_HOUR_COUNT;
QUARTER_HOUR_COUNT = QUARTER_HOUR_COUNT;
 

Et puis, évidemment, cela se décomposera davantage, mais ce qui précède devrait suffire pour illustrer mon propos.

Donc, techniquement, il existera avec une valeur par défaut de zéro au moment où il sera utilisé.

0voto

RobV Points 13708

Comme d'autres ont des types de valeurs implicites comme int ont une valeur par défaut, donc déclarer une variable sans l'initialiser explicitement signifie qu'elle a toujours une valeur.

Vous pouvez trouver la valeur par défaut pour tout type comme ceci:

 int i = default(int);
 

Ou plus généralement:

 T t = default(T);
 

Notez que pour les types de référence, la valeur par défaut sera null , seuls les types de valeur auront des valeurs par défaut.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X