Voir la section 4.1.5 du C# 4.0 spécification du langage. En particulier, de l'intérêt:
C# supporte les neuf types intégraux: sbyte, byte, short, ushort, int, uint, long, ulong, et l'omble chevalier. [omis texte]
L'intégrale de type les opérateurs unaires et binaires fonctionnent toujours avec une
signé de 32 bits non signé de 32 bits, 64 bits signé
ou la précision de 64 bits non signé de précision:
[omis des points de balle]
Pour le binaire +, –, *, /, %, &, ^, |, ==, !=, >, <, >=, et <=
les opérateurs, les opérandes sont convertis en type T, où T est le premier
de type int, uint, long, et ulong que peut bien représenter tous les possibles
les valeurs des deux opérandes. L'opération est ensuite effectuée en utilisant les
la précision de type T, et le type de résultat est T (ou bool pour l'
opérateurs relationnels). Il n'est pas permis pour un opérande de
de type long et de l'autre pour être de type ulong avec les opérateurs binaires.
Opérations à l'aide de courts sont promus en int, et ces opérations sont levées pour leur nullable homologues. (Ce qui conduit à des sections 7.3.6.2 et 7.3.7)
Ok, c'est par la Conception, mais ne comprends toujours pas pourquoi ils font ça, ils ont d'optimiser la chaîne ajoute trop, pourquoi la gauche les chiffres à eux seuls et ajouter plus de code pour cette simple comparaison
C'est simplement la manière dont le langage est conçu, avec une considération pour les optimisations dans l'architecture moderne. Pas spécifiquement dans ce contexte, mais estiment que les paroles de Eric Lippert comme indiqué ici
L'arithmétique n'est jamais fait en short en C#. L'arithmétique peut être fait dans les entiers, les nombres uint compris, longs et ulongs, mais l'arithmétique n'est plus à faire en short. Short de promouvoir l'int et le calcul est fait en ints, parce que, comme je l'ai dit avant, la grande majorité des calculs arithmétiques de s'insérer dans un int. La grande majorité ne rentre pas dans un court. Court arithmétique est peut-être plus lente sur du matériel moderne, qui est optimisé pour les entiers, et court arithmétique ne pas prendre moins de place, ça va être fait dans les ints ou longs sur la puce.
Votre dernière mise à jour:
Ce que j'attends le compilateur à faire est de faire une vérification simple avec .HasValue if (cTestA.HasValue){} au moins ce est ce que je fais sur mon code après je découvre cette conversion. C'est donc ce que je ne comprends vraiment pas pourquoi ne pas faire simple pense, mais tout ajouter ce code supplémentaire. Le compilateur essaie toujours d'optimiser le code - pourquoi ici d'éviter que simple .HasValue vérifier. Il me manque quelque chose ici pour vous...
Je vais avoir à s'en remettre à un compilateur expert pour dire pourquoi ils choisissent d'aller pour la conversion à la place de l'immédiat HasValue vérifier, sauf à dire qu'il pourrait être simplement un ordre des opérations. La spécification du langage dit opérateur binaire opérandes sont promus, et c'est ce qu'ils ont fait dans l'extrait de code. La spécification du langage se passe pour le dire plus tard que les vérifications x == null
, où x est une valeur de type nullable, peuvent être convertis en !x.HasValue
, et c'est aussi ce qu'ils ont fait. Dans le code compilé vous avez présenté, le numérique, la promotion a simplement pris la priorité sur la nullable comportement.
Comme pour le compilateur toujours essayer d'optimiser le code, à nouveau, un expert peut préciser, mais ce n'est pas le cas. Il y a des optimisations qu'il peut faire et d'autres, il s'en remet donc à peut-être la gigue. Il y a des optimisations que soit le compilateur ou le scintillement peut ou ne peut pas faire, selon qu'on est un débogage et la libération de construire, avec ou sans un débogueur. Et sans doute il y a des optimisations qu'ils pouvaient faire ce qu'ils simplement choisir de ne pas, parce que les coûts et les avantages de ne pas jouer.