Aller au contenu principal

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

  1. Types primitifs

    • Testez tous les types primitifs
    • Comprenez les limites (min/max)
    • Testez les conversions implicites
  2. Value vs Reference

    • Testez le comportement des value types
    • Testez le comportement des reference types
    • Comprenez les différences
  3. Nullable types

    • Créez des variables nullable
    • Testez les null-aware operators
    • Utilisez HasValue et Value
  4. Conversions

    • Testez les conversions implicites
    • Testez les casts explicites
    • Utilisez Parse et TryParse
  5. Vérifications

    • Utilisez is et as
    • Testez typeof et GetType
    • Comprenez les différences

Quiz

  1. 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
  2. Comment déclarer un int nullable ?

    • nullable int
    • int?
    • int null
  3. Que fait l'opérateur ?? ?

    • Compare deux valeurs
    • Valeur par défaut si null
    • Force non-null
  4. Quelle méthode parse de manière sécurisée ?

    • Parse()
    • TryParse()
    • Convert()
  5. 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 :

  1. Validation (estNombre, estEntier, estChaine)
  2. Conversion sécurisée (versInt, versDouble avec défaut)
  3. Gestion nullable (valeurs nullable, opérateurs null-aware)
  4. 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.