Pourquoi la première et la deuxième écriture fonctionnent-elles mais pas la dernière? Existe-t-il un moyen de les autoriser tous les 3 et de détecter si c'était 1, (int) 1 ou si je suis passé? Et vraiment pourquoi est-il permis mais le dernier? Le second étant autorisé mais pas le dernier me souffle vraiment.
Démo pour afficher l'erreur de compilation
using System;
class Program
{
public static void Write(short v) { }
static void Main(string[] args)
{
Write(1);//ok
Write((int)1);//ok
int i=1;
Write(i);//error!?
}
}
c#
compiler-errors
int
type-conversion
implicit-conversion
CodesInChaos
la source
la source
(short) i
.Réponses:
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 garantir que la valeur correspond au type cible, mais il ne le peut pas pour les expressions normales.
Cette règle est conforme à la directive selon laquelle les conversions implicites doivent être sans perte.
(Cité de C # Language Specification Version 3.0)
la source
Il n'y a pas de conversion implicite de
int
à enshort
raison de la possibilité de troncature. Cependant, une expression constante peut être traitée comme étant du type cible par le compilateur .1
? Pas de problème: c'est clairement uneshort
valeur 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.la source
Expression<Func<int>>
? Ensuite, vous pouvez passer() => 1
ou() => i
et à l'intérieur de la fonction, vous pouvez vérifier si l'entité transmise contient une variable capturée ou une valeur constante.un
int
littéral peut être implicitement converti enshort
. Tandis que:Ainsi, les deux premiers fonctionnent car la conversion implicite de littéraux est autorisée.
la source
Je crois que c'est parce que vous passez un littéral / constant dans les deux premiers, mais il n'y a pas de conversion de type automatique lors du passage d'un entier dans le troisième.
Edit: Quelqu'un m'a battu!
la source
Parce qu'il n'y aura aucune conversion implicite entre le type non littéral en short de plus grande taille.
La conversion implicite n'est possible que pour l'expression constante.
Où lorsque vous passez la
integer
valeur comme argument àshort
la source
Le compilateur vous a expliqué pourquoi le code échoue:
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
short
mot clé:http://msdn.microsoft.com/en-us/library/ybs77ex4(v=vs.71).aspx
Comme l'indique cette page, les transtypages implicites d'un type de données plus grand vers
short
ne sont autorisés que pour les littéraux. Le compilateur peut dire quand un littéral est hors de portée, mais pas autrement, il doit donc être assuré que vous avez évité une erreur hors de portée dans la logique de votre programme. Cette assurance est fournie par un casting.la source
La conversion de int -> short peut entraîner une troncature des données. C'est pourquoi.
la source