• 20 hours
  • Easy

Free online content available in this course.

Paperback available in this course

course.header.alt.is_certifying

You can get support and mentoring from a private teacher via videoconference on this course.

Got it!

Last updated on 11/28/19

Les conversions entre les types

Log in or subscribe for free to enjoy all this course has to offer!

Nous avons vu que le C# est un langage qui possède plein de types de données différents : entier, décimal, chaîne de caractères, etc.   

Dans nos programmes, nous allons très souvent avoir besoin de manipuler des données entre elles alors qu'elles ne sont pas forcément du même type. Lorsque cela sera possible, nous aurons besoin de convertir un type de données en un autre.

Entre les types compatibles : Le casting

C’est l’heure de faire la sélection des types les plus performants, place au casting ! Le jury est en place, à vos SMS pour voter.

Ah, on me fait signe qu’il ne s’agirait pas de ce casting là … :) .

Plus précisément, cela fonctionne pour les types qui sont compatibles entre eux, entendez par là « qui se ressemblent ».

Par exemple, l'entier et le petit entier se ressemblent. Pour rappel, nous avons :

Type

Description

short

Entier de -32768 à 32767

int

Entier de -2147483648 à 2147483647

Ils ne diffèrent que par leur capacité. Le short ne pourra pas contenir le nombre 100000 par exemple, alors que l'int le pourra.

Nous ne l'avons pas encore fait, mais le C# nous autorise à faire :

short s = 200;
int i = s;

Car il est toujours possible de stocker un petit entier dans un grand. Peu importe la valeur de s, i sera toujours à même de contenir sa valeur. C'est comme dans une voiture, si nous arrivons à tenir à 5 dans un monospace, nous pourrons facilement tenir à 5 dans un bus.

L'inverse n'est pas vrai bien sûr, si nous tenons à 100 dans un bus, ce n'est pas certain que nous pourrons tenir dans le monospace, même en se serrant bien.

Ce qui fait que si nous faisons :

int i = 100000;
short s = i;

nous aurons l'erreur de compilation suivante :

Impossible de convertir implicitement le type 'int' en 'short'. Une conversion explicite existe (un cast est-il manquant ?)

Et oui, comment pouvons-nous faire rentrer 100000 dans un type qui ne peut aller que jusqu'à 32767 ? Le compilateur le sait bien.

Vous remarquerez que nous aurons cependant la même erreur si nous tentons de faire :

int i = 200;
short s = i;

Mais pourquoi ? Le short est bien capable de stocker la valeur 200 ?

Oui tout à fait, mais le compilateur nous avertit quand même. Il nous dit :

Nous avons envie de lui répondre :

(on se parle souvent avec mon compilateur !)

Et bien, ceci s'écrit en C# de la manière suivante :

int i = 200;
short s = (short)i;

Pour faire un tel cast, il suffit de précéder la variable à convertir du nom du type souhaité entre parenthèses. Ce qui permet d'indiquer à notre compilateur que nous savons ce que nous faisons, et que l'entier tiendra correctement dans le petit entier.

Mais attention, le compilateur nous fait confiance. Nous sommes le boss ! Cela implique une certaine responsabilité, il ne faut pas faire n'importe quoi.

Si nous faisons :

int i = 40000;
short s = (short)i;
Console.WriteLine(s);
Console.WriteLine(i);

nous tentons de faire rentrer un trop gros entier dans ce qu'est capable de stocker le petit entier.

Si nous exécutons notre application, nous aurons :

Image utilisateur

Le résultat n'est pas du tout celui attendu. Nous avons fait n'importe quoi, le C# nous a punis. :diable:

En fait, plus précisément, il s'est passé ce qu'on appelle un dépassement de capacité. Nous l'avons déjà vu lors du chapitre sur les boucles. Ici, il s'est produit la même chose. Le petit entier est allé à sa valeur maximale puis a bouclé en repartant de sa valeur minimale.

Bref, tout ça pour dire que nous obtenons un résultat inattendu. Il faut donc faire attention à ce que l'on fait et honorer la confiance que nous porte le compilateur. Bien faire attention à ce que l'on caste.

D'une façon similaire à l'entier et au petit entier, l'entier et le double se ressemblent un peu. Ce sont tous les deux des types permettant de contenir des nombres. Le premier permet de contenir des nombres entiers, le deuxième pouvant contenir des nombres à virgules.

Ainsi, nous pouvons faire le code C# suivant :

int i = 20;
double d = i;

En effet, un double est plus précis qu’un entier. Il est capable d’avoir des chiffres après la virgule alors que l’entier ne le peut pas. Ce qui fait que le double est entièrement capable de stocker toute la valeur d’un entier sans perdre d’information dans cette affectation.

Par contre, comme on peut s'y attendre, l’inverse n’est pas possible. Le code suivant :

double prix = 125.55;
int valeur = prix;

produira l’erreur de compilation suivante :

Impossible de convertir implicitement le type 'double' en 'int'. Une conversion explicite existe (un cast est-il manquant ?)

En effet, un double étant plus précis qu’un entier, si nous mettons ce double dans l’entier nous allons perdre notamment les chiffres après la virgule.

Il restera encore une fois à demander au compilateur de nous faire confiance !

Ce qui s’écrit en C# de cette manière, comme nous l'avons vu :

double prix = 125.55;
int valeur = (int)prix; // valeur vaut 125

Nous faisons précéder la variable prix du type dans lequel nous voulons la convertir en utilisant les parenthèses.

C'est plutôt sympa comme instruction. Mais n'oubliez-pas que cette opération est possible uniquement avec les types qui se ressemblent entre eux.

Par exemple, le cast suivant est impossible :

string nombre = "123";
int valeur = (int)nombre;

car les deux types sont trop différents et sont incompatibles entre eux. Même si la chaine de caractères représente un nombre.

Nous verrons plus loin comment convertir une chaîne en entier. Pour l’instant, Visual Studio Express nous génère une erreur de compilation :

Impossible de convertir le type 'string' en 'int'

Nous avons vu précédemment que les énumérations représentaient des valeurs entières. Il est donc possible de récupérer l’entier correspondant à une valeur de l’énumération grâce à un cast.

Par exemple, en considérant l’énumération suivante :

enum Jours
{
    Lundi = 5, // lundi vaut 5
    Mardi, // mardi vaut 6
    Mercredi = 9, // mercredi vaut 9
    Jeudi = 10, // jeudi vaut 10
    Vendredi, // vendredi vaut 11
    Samedi, // samedi vaut 12
    Dimanche = 20 // dimanche vaut 20
}

Le code suivant :

int valeur = (int)Jours.Lundi; // valeur vaut 5

convertit l’énumération en entier.

Nous verrons dans le prochain cours que le cast est beaucoup plus puissant que ça, mais pour l’instant, nous n’avons pas assez de connaissances pour tout étudier.

Entre les types incompatibles

Nous avons vu qu’il était facile de convertir des types qui se ressemblent grâce au cast. Il est parfois possible de convertir des types qui ne se ressemblent pas mais qui ont le même sens.

Par exemple, il est possible de convertir une chaine de caractères qui contient uniquement des chiffres en un nombre (entier, décimal, …). Cette conversion va nous servir énormément car dès qu’un utilisateur va saisir une information par le clavier, elle sera représentée par une chaine de caractères. Donc si on lui demande de saisir un nombre, il faut être capable d’utiliser sa saisie comme un nombre afin de le transformer, de le stocker, etc …

Pour ce faire, il existe plusieurs solutions. La plus simple est d’utiliser la méthode Convert.ToInt32() disponible dans le framework .NET.
Par exemple :

string chaineAge = "20";
int age = Convert.ToInt32(chaineAge); // age vaut 20

Cette méthode, bien que simple d’utilisation, pose un inconvénient dans le cas où la chaine ne représente pas un entier. À ce moment-là, la conversion va échouer et le C# va renvoyer une erreur au moment de l’exécution.

Par exemple :

string chaineAge = "vingt ans";
int age = Convert.ToInt32(chaineAge);

Si vous exécutez ce bout de code, vous verrez :

Image utilisateur

La console nous affiche ce que l’on appelle une exception. Il s’agit tout simplement d’une erreur. Nous aurons l’occasion d’étudier plus en détail les exceptions dans le prochain cours.
Pour l’instant, on a juste besoin de voir que ceci ne nous convient pas. L’erreur est explicite « Le format de la chaine d’entrée est incorrect », mais cela se passe au moment de l’exécution et notre programme « plante » lamentablement.
Nous verrons dans le chapitre sur les exceptions comment gérer les erreurs.

En interne, la méthode Convert.ToInt32() utilise une autre méthode pour faire la conversion, il s’agit de la méthode int.Parse(). Donc plutôt que d’utiliser une méthode qui en appelle une autre, nous pouvons nous en servir directement, par exemple :

string chaineAge = "20";
int age = int.Parse(chaineAge); // age vaut 20

Bien sûr, il se passera exactement la même chose que précédemment quand la chaine ne représentera pas un entier correct.

Il existe par contre une autre façon de convertir une chaine en entier qui ne provoque pas d’erreur quand le format n’est pas correct et qui nous informe si la conversion s’est bien passée ou non, c’est la méthode int.TryParse() qui s’utilise ainsi :

string chaineAge = "ab20cd";
int age;
if (int.TryParse(chaineAge, out age))
{
    Console.WriteLine("La conversion est possible, age vaut " + age);
}
else
{
    Console.WriteLine("Conversion impossible");
}

Et nous aurons :

Image utilisateur

La méthode int.TryParse nous renvoie vrai si la conversion est bonne, faux sinon. Nous pouvons donc effectuer une action en fonction du résultat grâce aux if/else. On passe en paramètres la chaine à convertir et la variable où l’on veut stocker le résultat de la conversion. Le mot clé « out» signifie juste que la variable est modifiée par la méthode, nous verrons exactement de quoi il s’agit dans le prochain cours.

Les méthodes que nous venons de voir Convert.ToString() ou int.TryParse() se déclinent en général pour tous les types de bases, par exemple double.TryParse() ou Convert.ToDecimal(), etc.

En résumé
  • Il est possible, avec le casting, de convertir la valeur d’un type dans un autre lorsqu’ils sont compatibles entre eux.

  • Le casting explicite s’utilise en préfixant une variable par un type précisé entre parenthèses.

  • Le framework .NET possède des méthodes permettant de convertir des types incompatibles entre eux s’ils sont sémantiquement proches.

Example of certificate of achievement
Example of certificate of achievement