Dans de nombreux contextes où une méthode ou un argument d'opérateur n'est pas du type requis, le compilateur C # tentera d'effectuer une conversion de type implicite. Si le compilateur peut faire en sorte que tous les arguments satisfassent leurs opérateurs et méthodes en ajoutant des conversions implicites, il le fera sans se plaindre, même si dans certains cas (surtout avec des tests d'égalité!) Les résultats peuvent être surprenants.
En outre, chaque type de valeur tel que int
ou short
décrit en fait à la fois un type de valeur et un type d'objet (*). Des conversions implicites existent pour convertir des valeurs en d'autres types de valeurs et pour convertir tout type de valeur en son type d'objet correspondant, mais les différents types d'objets ne sont pas implicitement convertibles les uns aux autres.
Si l'on utilise l' ==
opérateur pour comparer a short
et an int
, le short
sera implicitement converti en un int
. Si sa valeur numérique était égale à celle du int
, le int
auquel il a été converti sera égal int
au auquel il est comparé. Si l'on tente d'utiliser la Equals
méthode sur le short pour la comparer à un int
, cependant, la seule conversion implicite qui satisferait une surcharge de la Equals
méthode serait la conversion vers le type d'objet correspondant à int
. Lorsqu'on short
lui demande s'il correspond à l'objet passé, il observera que l'objet en question est un int
plutôt qu'un a short
et conclura ainsi qu'il ne peut pas être égal.
En général, même si le compilateur ne s'en plaindra pas, il faut éviter de comparer des choses qui ne sont pas du même type; si l'on veut savoir si la conversion des choses en une forme commune donnerait le même résultat, on devrait effectuer une telle conversion explicitement. Considérez, par exemple,
int i = 16777217;
float f = 16777216.0f;
Console.WriteLine("{0}", i==f);
Il existe trois manières de comparer un int
à un float
. On pourrait vouloir savoir:
- La
float
valeur la plus proche possible du int
correspond-elle à la float
?
- Est-ce que la partie du nombre entier
float
correspond au int
?
- Faites
int
et float
représentez la même valeur numérique.
Si l'on essaie de comparer un int
et float
directement, le code compilé répondra à la première question; si c'est ce que le programmeur a voulu, cependant, sera loin d'être évident. Changer la comparaison en (float)i == f
indiquerait clairement que le premier sens était voulu, ou (double)i == (double)f
amènerait le code à répondre à la troisième question (et indiquerait clairement que c'est ce qui était prévu).
(*) Même si la spécification C # considère une valeur de type par exemple System.Int32
comme étant un objet de type System.Int32
, une telle vue est contredite par l'exigence qu'un code s'exécute sur une plate-forme dont la spécification considère les valeurs et les objets comme habitant des univers différents. De plus, si T
est un type de référence, et x
est a T
, alors une référence de type T
devrait pouvoir faire référence x
. Ainsi, si une variable v
de type Int32
contient an Object
, une référence de type Object
doit pouvoir contenir une référence à v
ou à son contenu. En fait, une référence de type Object
pourrait pointer vers un objet contenant des données copiées v
, mais pas vers v
lui-même ni vers son contenu. Cela suggérerait que niv
ni son contenu n'est vraiment un Object
.