Pourquoi puis-je passer 1 en tant que court, mais pas la variable int i?

Pourquoi la première et la deuxième écriture fonctionnent-elles mais pas la dernière? Y a-t-il un moyen de les autoriser tous les trois et de détecter si c’était 1, (int) 1 ou si je suis passé? Et vraiment pourquoi est-il permis mais le dernier? La seconde étant permise mais pas la dernière me souffle vraiment.

Démo pour afficher l’erreur de compilation

using System; class Program { public static void Write(short v) { } static void Main(ssortingng[] args) { Write(1);//ok Write((int)1);//ok int i=1; Write(i);//error!? } } 

Les deux premiers sont des expressions constantes, le dernier ne l’est pas.

La spécification C # permet une conversion implicite de int en short pour les constantes, mais pas pour les autres expressions. C’est une règle raisonnable, car pour les constantes, le compilateur peut s’assurer que la valeur rentre dans le type de cible, mais pas pour les expressions normales.

Cette règle est conforme à la directive selon laquelle les conversions implicites doivent être sans perte.

6.1.8 Conversions d’expression constante implicite

Une conversion implicite d’expression constante permet les conversions suivantes:

  • Une expression constante (§7.18) de type int peut être convertie en type sbyte , byte , short , ushort , uint ou ulong , à condition que la valeur de l’ expression constante soit comprise dans la plage du type de destination.
  • Une expression constante de type long peut être convertie en type ulong , à condition que la valeur de l’ expression constante ne soit pas négative.

(Cité à partir de la spécification du langage C # Version 3.0)

Il n’y a pas de conversion implicite de int à short raison de la possibilité de troncature. Cependant, une expression constante peut être traitée comme étant du type cible par le compilateur .

1 ? Pas un problème: c’est clairement une valeur short valide. i ? Pas tellement – cela pourrait être une valeur> short.MaxValue par exemple, et le compilateur ne peut pas vérifier cela dans le cas général.

un littéral int peut être implicitement converti en short . Tandis que:

Vous ne pouvez pas convertir implicitement des types numériques non littéraux de taille de stockage supérieure en caractères courts.

Donc, les deux premiers fonctionnent parce que la conversion implicite des littéraux est autorisée.

Je crois que c’est parce que vous transmettez un littéral / une constante dans les deux premiers, mais il n’y a pas de conversion automatique de type lors du passage d’un entier dans le troisième.

Edit: Quelqu’un m’a battu à ça!

Car il n’y aura pas de conversion implicite entre le type Nonliteral en plus petit format.

La conversion implicite n’est possible que pour l’expression constante.

 public static void Write(short v) { } 

Où comme vous passez la valeur integer comme argument à short

 int i=1; Write(i); //Which is Nonliteral here 

Le compilateur vous a dit pourquoi le code échouait:

 cannot convert `int' expression to type `short' 

Alors, voici la question que vous devriez vous poser: pourquoi cette conversion échoue-t-elle? J’ai googlé “c # convert int short” et je me suis retrouvé sur la page MS C # pour le mot-clé short :

http://msdn.microsoft.com/en-us/library/ybs77ex4(v=vs.71).aspx

Comme le dit cette page, les conversions implicites d’un type de données plus volumineux à un type plus short ne sont autorisées que pour les littéraux. Le compilateur peut dire quand un littéral est hors de scope, mais pas autrement, il faut donc être sûr que vous avez évité une erreur hors plage dans la logique de votre programme. Cette réassurance est fournie par un casting.

 Write((short)i) 

La conversion de int -> short peut entraîner une troncature des données. C’est pourquoi.