Une remarque pertinente ? Une critique impertinente ? Un lynchage en règle ? Une invitation sous les tropiques ? Ecrivez-moi ! |
|
Conçu et enseigné tel qu'en lui même, avec pertes, fracas et
humour de qualité supérieure par Christophe Darmangeat dans le M2 PISE du Master MECI (Université Paris 7) |
|
LE COURS 10. Les graphismes
11. Les menus
AIDES-MÉMOIRES • Conversion et « cast »
CHOSES DIVERSES Souvent Posées Questions
Liens utiles
|
Référence du langage
Les conversions de typesComme dans tous les langages informatiques, les informations en C# sont stockées dans des blocs de mémoire, en réservant un certain nombre d'octets et en utilisant une certaine méhode de codage. Ce que l'on résume en disant que les variables ont un type. Oui mais voilà, il arrive très souvent qu'au cours d'une application, on ait besoin de reverser les informations stockées dans des variables d'un certain type vers des variables d'un autre type, ce qu'on appelle la conversion. Les langages ont tous une approche différente du problème des types et des conversions.
Pour prendre un parallèle avec notre belle planète, en Python, on est dans un monde sans frontières : chacun individu est libre de voyager et de s'établir où il veut sans que personne ne lui demande rien. En VB.Net, il y a des frontières et les individus possèdent des nationalités, mais les douaniers ne sont pas spécialement pénibles, et ne contrôlent les passeports qu'en cas de problème avéré. Avec C#, on est dans notre monde réel, celui ou le franchissement de (certaines) frontières donnera lieu à mille tracasseries, inspirant de belles oeuvres telles que Welcome, Continents à la dérive ou Le vaisseau des morts... Ce qui est une calamité inhumaine dans le monde réel possède certains avantages en programmation : si, en C#, le compilateur va surveiller nos variables de très près, ce sera pour nous autres programmeurs la garantie que nos applications manipulent les variables de manière rationnelles, et que nous ne sommes pas entrain de leur faire faire n'importe quoi. 1. Entre types compatiblesOn sait qu'en informatique, certains types ne sont que des versions plus larges d'autres types. Ainsi, parmi les entiers, le long est une version plus puissante du int, qui est lui-même une version plus puissante du short. Parmi les nombres à virgule, le double est une version plus puissante du float. 1.1 Depuis la petite boîte vers la grandeC'est évidemment le cas le plus facile : « qui peut le plus, peut le moins », comme le sait la sagesse populaire. Une valeur qui loge dans une « petite » variable logera a fortiori dans une plus grande. Dans ce cas – et c'est bien le seul – les douaniers nous laissent passer sans nous poser de questions :
int petit = 12 542; Et l'affaire est dans le sac. 1.2 Depuis la grande boîte vers la petite : le castingLà où les choses se compliquent un peu, c'est lorsqu'on veut passer le contenu depuis un type plus large vers un type plus étroit. En effet, rien ne dit que ça va rentrer... Aussi, conformément à sa philosophie générale, C# nous oblige à demander expressément une autorisation à la maréchaussée, en baptisant au passage cette opération du terme de « casting » (ah là là, ces informaticiens, toujours en train de se la péter avec du jargon franglais...) Voici donc la syntaxe pour « caster » (et pourquoi j'aurais pas le droit, moi aussi, de me la raconter ?) un long vers un int :
long grand = 12 542; Une telle opération se fera à nos risques et périls : on peut demander à une machine de verser 2 litres d'eau dans une bouteille de 1 litre... mais alors, fatalement ça déborde. Recopier un long dans un int ne pose donc aucun problème... à condition que la valeur contenue dans le long n'excède pas 2 147 483 647. Que se passera-t-il dans le cas contraire ?
Tout dépend des types concernés. Il pourra arriver que l'exécution s'interrompe dans un long hurlement de douleur, et dans un message ne laissant aucun doute sur l'origine du mal. Il pourra aussi arriver, de manière plus vicieuse, qu'aucune erreur ne soit signalée, mais que la machine tronque allègrement la valeur concernée, inscrivant ainsi un résultat totalement fantaisiste dans la variable de destination... 2. Entre types de nature différentesCe que l'on a dit jusqu'ici concernanit les transferts au sein de types globalement similaires : des entiers, des décimaux (et, ajouterai-je : des contrôles). Mais il se peut qu'ait à convertir des types qui n'ont a priori rien à voir les uns avec les autres. Typiquement, le cas ultra-classique est celui de la chaîne de caractères qui contient un nombre, entier ou décimal, sous forme d'une série de caractère, et qu'on veut récupérer en tant que nombre. Ou, inversement, de la variable numérique qu'on veut transformer en chaîne pour l'afficher quelque part sur la Form. C# offre deux catégories de solutions en pareil cas : 2.1 La technique sans filetIl existe une série de méthodes de la classe Convert, qui permettent de convertir tout type en un autre. Typiquement, Convert.ToInt32 convertit une chaîne en entier ; Convert.ToString convertit tout nombre en chaîne, etc. Le truc, en particulier si l'on convertit une chaîne en nombre, c'est qu'on n'est pas forcémen certain que la chaîne correspond bien à un nombre valide. Si ce le cas, pas de problème. Mais si la chaîne contient par exemple « James007 », sa conversion en entier provoquera illico une exception, c'est-à-dire un crash de l'application. 2.2 La technique avec filetAussi pourra-t-on, au moins dans certaines circonstances, préférer la méthode TryParse, disponible pour tous les types de données. Cette méthode renvoie un booléen qui indique si la conversion s'est bien déroulée ou non, ainsi qu'un paramètre en sortie – la variable contenant éventuellement la valeur une fois convertie. Une conversion de la chaîne matricule vers un entier numMatricule pourra aini s'écrire :
if (int.TryParse(chaineAge, out numMatricule)) |