54 votes

Déduire une constante en C #

En C #, l'inférence de type suivante fonctionne:

 var s = "abcd";
 

Mais pourquoi le type ne peut-il pas être déduit lorsque la variable est une constante?

Ce qui suit lève une exception au moment de la compilation:

 const var s = "abcd"; // <= Compile time error: 
                      //    Implicitly-typed local variables cannot be constant
 

46voto

Eric Lippert Points 300275

En fait, je suis en espérant Lippert pop par et et se penche sur la question

Si il y a quelque chose que vous voulez porté à mon attention, vous pouvez laisser mon nom dans le texte -- pas un commentaire -- et je vais trouver finalement. Ou, mieux, vous pouvez le "tweet" de @ericlippert. Notez que cela ne constitue pas un accord de niveau de service; je le fais dans mon temps libre.

pourquoi ne peut pas le type de l'être déduite lorsque la variable est une constante?

"constant" et "variable" sont opposés. const var me donne les frissons de type. Une constante est une valeur qui ne change jamais et n'a pas d'emplacement de stockage; une variable est un emplacement de stockage dont le contenu change. Ils sont complètement différents, donc n'essayez pas de les combiner. L' var de la syntaxe a été choisi d'appeler "c'est une variable", et nous sommes coller avec elle.

var peut représenter un type spécifique de la déclaration, mais en les combinant avec d' const sévèrement brouille l'image de ce que le compilateur n'a de la valeur. Par conséquent, const var est désactivé pour éviter cette confusion et vous devez taper votre constantes.

Je serais parfaitement bien avec déduite des constantes qui n'utilisent pas d' var:

const Pi = 3.14159;

semble bien pour moi. Cependant, je ne connais pas les plans de l'ajouter à C#.

19voto

Je suis d'accord avec Eric que c'est laid comme péché:

const var s = "abcd"

Mais pourquoi pas simplement ça?

const s = "abcd"

Cela me semble une syntaxe raisonnable.

12voto

Kevin Won Points 3697

C'est juste une supposition, mais je pense que la raison pourrait avoir à faire avec le fait que const valeurs dans les métadonnées (qui a subtils conséquences tout, c'est propre) lors de la compilation. Je me demande si peut-être que le compilateur a quelques problèmes à trouver comment transformer une var de métadonnées.

Dans Richter CLR VIA C# (page 177),

La définition d'une constante provoque la création de métadonnées. Lorsque le code se réfère à une constante de symbole, les compilateurs rechercher ce symbole dans les métadonnées de la assemblée qui définit la constante, extrait de la constante de valeur, et incorporer la valeur dans le émise IL code.

Il fait la remarque que cela signifie que vous ne pouvez pas faire référence à la mémoire d'une constante pour cette raison. Pour rendre tout ceci un peu plus explicite, dans la pseudo C# si le montage A définit un const:

//Assembly A, Class Widget defines this:
public static const System.Decimal Pi = 3.14

ensuite, vous avez un consommateur d'Un:

//somewhere in the Program.exe assembly
decimal myCircleCurcum = 2 * Widget.pi

la résultante compilé IL de program.exe ferais quelque chose comme ce pseudo-code:

// pseudo-IL just to illustrate what would happen to the const
myCircleCurcum = 2*3.14

notez que la consommer de l'assemblée n'a aucune idée que le séparateur décimal 3.14 avait aucune relation à l'Assemblée Une à tous--c'est à program.exe une valeur littérale. Cela, pour moi, est un moyen raisonnable pour le compilateur C# de loi--après tout, l'Assemblée A déclaré explicitement que pi est une constante (ce qui signifie que la valeur est une fois pour toutes pi=3.14). Mais, je me risquerais à deviner, que 99% de C# développeurs ne comprennent pas les conséquences de cette & peut changer pi être 3.1415 sur un coup de tête.

Les constantes ont une très mauvaise de la croix-version de l'assembly histoire (encore une fois, cela vient de Richter) parce que le consommateur de l'assemblée avec une constante dans il ne va pas voir un changement si le montage d'Un constant changement (c'est à dire qu'il a été recompilé). Cela peut entraîner vraiment difficile de comprendre bugs par la consommation de l'assemblée A. . . tellement que je ban mon équipe à partir de l'utilisation des constantes. Leur léger gain de perf n'est pas la peine de les bogues subtils qu'ils peuvent causer.

Vous pouvez vraiment ne jamais utiliser une constante si vous savez que la valeur ne changera jamais , et même avec quelque chose comme const tels que pi, vous ne pouvez pas dire à coup sûr que vous ne voulez pas que votre precision changer dans le futur.

si l'assemblée définit:

decimal const pi = 3.14

ensuite, vous construisez et puis d'autres assemblées consommer, si vous changez de l'assemblée:

decimal const pi = 3.1415

et la reconstruction de l'assemblée, le consommateur de l'assemblée auront toujours l'ancienne valeur 3.14! pourquoi? parce que l'original 3.14 a été défini comme une constante, ce qui signifie que les consommateurs de l'assemblée a été dit que la valeur ne change pas, de sorte qu'ils peuvent cuire que la valeur de pi dans leurs propres métadonnées (si vous reconstruire des consommateurs de l'assemblée, il sera alors obtenir la nouvelle valeur de pi dans les métadonnées). Encore une fois, je ne vois pas cela comme un problème avec la façon dont le SCC gère des constantes, c'est juste que les développeurs n'est probablement pas s'attendre à ce que d'une constante ne peut pas être modifié de façon sécuritaire dans certaines circonstances, où il peut être modifié en toute sécurité dans d'autres. Sécurité: pas de consommateurs aura jamais de référence .dll uniquement (c'est à dire qu'ils seront toujours à construire à partir de la source à CHAQUE FOIS), dangereux: les consommateurs n'ont pas la moindre idée de quand le code source de votre assemblée avec la const définie, elle bascule. Elle doit probablement être beaucoup plus claire .NET documentation constante signifie que vous ne pouvez pas modifier la valeur dans le code source

Pour cette raison, j'avais recommandons fortement de ne pas utiliser des constantes et au lieu de simplement faire le widget en lecture seule. Combien de valeurs peut-on vraiment dire que certains sont vraiment va être const pour toujours et toujours?

La seule vraie raison d'utiliser const plus readonly dans mon esprit est si quelque chose pourrait avoir des implications sur les performances... mais si vous êtes en cours d'exécution dans que, je me demande si C# est vraiment la bonne langue pour votre problème. En bref, pour moi, c'est alomst jamais une bonne idée d'utiliser des constantes. Il y a très peu de fois où la petite perf amélioration vaut la peine de les problèmes potentiels.

8voto

Mark Byers Points 318575

La réponse courte est parce que la langue des designers (Microsoft), dites-le.

À partir de MSDN:

Erreur de compilateur CS0822

Message d'erreur: Implicitement tapé habitants ne peut pas être const

Implicitement tapé les variables locales sont seulement nécessaire pour stocker l'anonyme les types. Dans tous les autres cas, ils sont juste une commodité. Si la valeur de la variable ne change jamais, il suffit de donner un type explicite. La tentative d'utilisation de le readonly modificateur avec un implicitement tapé local va générer CS0106.

Pour corriger cette erreur

Si vous avez besoin de la variable à être constant ou readonly, donnez-lui un de type explicite.

3voto

Je ne suis pas d'accord avec @Eric.

Le var mot-clé ne veut pas dire "c'est une variable", il signifie "le type est à déduire".

Fait int, long, etc. sont des "mots clés" pour identifier les variables? Non, ils sont juste des types de données, peut être utilisé pour des variables ou des constantes.

Je pense que le nom du mot-clé var a été pensé pour ressembler à Javascript et je considère inapproprié.

Que diriez - auto ? ( http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2004/n1705.pdf )

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