Module C#.4 – Types
Objectif
Maîtriser tous les types C# : types primitifs, différence entre value types et reference types, types nullable, et conversions pour manipuler les données efficacement.
Théorie
Types primitifs
C# a de nombreux types primitifs pour différents besoins.
Entiers
byte : 8 bits non signés (0 à 255)
byte b = 255;
byte zero = 0;
sbyte : 8 bits signés (-128 à 127)
sbyte sb = -128;
sbyte max = 127;
short : 16 bits signés (-32,768 à 32,767)
short s = -32768;
short max = 32767;
ushort : 16 bits non signés (0 à 65,535)
ushort us = 65535;
int : 32 bits signés (-2^31 à 2^31-1)
int i = -2147483648;
int max = 2147483647;
int hexa = 0xFF; // 255 en hexadécimal
int binaire = 0b1010; // 10 en binaire
uint : 32 bits non signés (0 à 2^32-1)
uint ui = 4294967295;
long : 64 bits signés
long l = -9223372036854775808L; // L obligatoire
long max = 9223372036854775807L;
ulong : 64 bits non signés
ulong ul = 18446744073709551615UL;
Décimaux
float : Simple précision (32 bits)
float f = 3.14f; // f obligatoire
float scientifique = 1.5e3f; // 1500.0
double : Double précision (64 bits)
double d = 3.141592653589793;
double scientifique = 1.5e3; // 1500.0
decimal : Précision décimale (128 bits) - Pour l'argent
decimal prix = 19.99m; // m obligatoire
decimal grand = 123456789.123456789m;
Quand utiliser quoi :
- float : Rarement (précision limitée)
- double : Par défaut pour décimaux
- decimal : Pour l'argent, calculs financiers (précision exacte)
Autres
char : Caractère Unicode (16 bits)
char c = 'A';
char unicode = '\u0041'; // 'A' en Unicode
char tab = '\t';
char newline = '\n';
bool : Booléen (true/false)
bool vrai = true;
bool faux = false;
string : Chaîne de caractères (reference type)
string nom = "Jean";
string multiLigne = @"Ligne 1
Ligne 2";
string verbatim = @"C:\Users\Documents"; // @ évite l'échappement
Value types vs Reference types
Value types
Stockés directement dans la pile (stack).
Types value :
- Types primitifs (int, double, bool, char)
- Structures (struct)
- Énumérations (enum)
Comportement :
int a = 10;
int b = a; // Copie la valeur
b = 20; // a reste 10 (indépendant)
Reference types
Stockent une référence (adresse mémoire) dans la pile, données dans le tas (heap).
Types reference :
- Classes
- Interfaces
- Tableaux
- string
- object
Comportement :
int[] arr1 = {1, 2, 3};
int[] arr2 = arr1; // Copie la référence (pas les données)
arr2[0] = 10; // arr1[0] devient aussi 10 (même objet)
Comparaison :
// Value types
int a = 10, b = 10;
bool egal = (a == b); // true (comparaison de valeurs)
// Reference types
string s1 = "test";
string s2 = "test";
bool egal1 = (s1 == s2); // true (string compare le contenu)
bool egal2 = (s1.Equals(s2)); // true
bool reference = ReferenceEquals(s1, s2); // true (même référence dans le pool)
// Objets
object o1 = new object();
object o2 = new object();
bool egal3 = (o1 == o2); // false (comparaison de références)
Nullable types
Permettent aux value types d'être null.
Syntaxe
int? age = null; // Nullable int
bool? estActif = null; // Nullable bool
double? prix = null; // Nullable double
Équivalent à :
Nullable<int> age = null; // Syntaxe longue
Vérification
HasValue et Value :
int? age = null;
if (age.HasValue)
{
Console.WriteLine(age.Value); // Accède à la valeur
}
Null-coalescing operator (??) :
int? age = null;
int ageFinal = age ?? 0; // 0 si age est null
Null-coalescing assignment (??=) :
int? age = null;
age ??= 0; // Assigné seulement si null
Null-conditional operator (?.) :
string? nom = null;
int? longueur = nom?.Length; // null si nom est null (pas d'erreur)
string majuscules = nom?.ToUpper() ?? "Vide";
Null-forgiving operator (!) :
string? nom = obtenirNom();
string force = nom!; // Force non-null (dangereux, peut crasher)
Conversions de types
Conversion implicite (widening)
Conversion automatique vers un type plus large.
byte b = 10;
short s = b; // byte → short
int i = s; // short → int
long l = i; // int → long
float f = l; // long → float
double d = f; // float → double
Conversion explicite (casting)
Conversion forcée vers un type plus petit.
int i = 300;
byte b = (byte)i; // 44 (troncature, perte de données)
double d = 3.14;
int i2 = (int)d; // 3 (troncature)
Attention : Perte de données possible.
Conversions avec méthodes
ToString :
int i = 42;
string s = i.ToString();
string s2 = $"{i}"; // Interpolation
Parse :
string s = "42";
int i = int.Parse(s); // Lance exception si échec
double d = double.Parse("3.14");
TryParse : Sécurisé, retourne bool
string s = "42";
if (int.TryParse(s, out int nombre))
{
Console.WriteLine($"Nombre : {nombre}");
}
else
{
Console.WriteLine("Nombre invalide");
}
Convert :
string s = "42";
int i = Convert.ToInt32(s);
double d = Convert.ToDouble("3.14");
Vérification de types
is : Vérifie le type
object obj = 42;
if (obj is int)
{
Console.WriteLine("C'est un int");
}
if (obj is int nombre)
{
Console.WriteLine($"Nombre : {nombre}"); // Pattern matching
}
as : Cast sécurisé (retourne null si échec)
object obj = "texte";
string? texte = obj as string; // null si cast impossible
typeof : Obtient le type
Type type = typeof(int);
Console.WriteLine(type.Name); // "Int32"
GetType : Type à l'exécution
object obj = 42;
Type type = obj.GetType();
Console.WriteLine(type.Name); // "Int32"
Exercice
-
Types primitifs
- Testez tous les types primitifs
- Comprenez les limites (min/max)
- Testez les conversions implicites
-
Value vs Reference
- Testez le comportement des value types
- Testez le comportement des reference types
- Comprenez les différences
-
Nullable types
- Créez des variables nullable
- Testez les null-aware operators
- Utilisez HasValue et Value
-
Conversions
- Testez les conversions implicites
- Testez les casts explicites
- Utilisez Parse et TryParse
-
Vérifications
- Utilisez is et as
- Testez typeof et GetType
- Comprenez les différences
Quiz
-
Quelle est la différence entre value et reference type ?
- Aucune différence
- Value = copie valeur, Reference = copie référence
- Reference est plus rapide
-
Comment déclarer un int nullable ?
- nullable int
- int?
- int null
-
Que fait l'opérateur ?? ?
- Compare deux valeurs
- Valeur par défaut si null
- Force non-null
-
Quelle méthode parse de manière sécurisée ?
- Parse()
- TryParse()
- Convert()
-
Que fait is avec pattern matching ?
- Vérifie seulement le type
- Vérifie le type et extrait la valeur
- Convertit le type
Mini défi
Mission : Créer un système de validation de types
Créez des fonctions qui valident et convertissent les types :
Fonctions :
- Validation (estNombre, estEntier, estChaine)
- Conversion sécurisée (versInt, versDouble avec défaut)
- Gestion nullable (valeurs nullable, opérateurs null-aware)
- Tests complets avec cas limites
Exemple :
int? age = VersInt("30", null); // 30
int? invalide = VersInt("abc", null); // null
double prix = VersDouble("19.99", 0.0); // 19.99
Critères :
- ✅ Utilisation correcte des types
- ✅ Nullable types appropriés
- ✅ TryParse pour sécurité
- ✅ Gestion d'erreurs complète
- ✅ Code bien documenté
Objectif : Maîtriser tous les types C# et savoir les valider et convertir correctement.
Validation : Vous pouvez passer au module suivant quand vous maîtrisez tous les types C# et leurs conversions.