Aller au contenu
Réussir mon BTS SIO

Tape une notion, une commande ou le nom d'une épreuve.

Par exemple

Chapitre 125 minIntermédiaire

Les bases de C# pour la POO

Par Josselyn C., prof de BTS SIO. Mis à jour le .

À la fin de ce chapitre, tu sauras

  • installer .NET 10 et créer une application console ;
  • choisir le bon type, notamment decimal pour l'argent ;
  • écrire conditions, boucles et méthodes en C# ;
  • mettre en forme un texte avec l'interpolation ;
  • manipuler une valeur qui peut être nulle sans planter.

5 exercices corrigés

C# (prononcé « C sharp ») est un langage de programmation de Microsoft, typé et compilé, qui tourne sur la plateforme .NET sous Windows, macOS et Linux. Ce chapitre installe ton environnement et te donne les bases du langage dont tu as besoin pour la suite du cours : types, variables, conditions, boucles, méthodes, interpolation de chaînes et types nullables. Si tu viens de JavaScript ou de l'algorithmique, tu retrouveras les mêmes idées avec une syntaxe plus stricte.

Pourquoi apprendre la POO en C#

La programmation orientée objet s'apprend dans n'importe quel langage objet : Java, C#, PHP, Python, TypeScript. Ce cours a choisi C# pour trois raisons.

  • Le typage strict t'aide à apprendre. Chaque variable a un type déclaré ; le compilateur refuse de ranger un texte dans un nombre ou d'appeler une méthode qui n'existe pas. Les erreurs de conception apparaissent avant l'exécution, avec un message qui dit où chercher.
  • Tout le vocabulaire de la POO existe en vrai. class, private, abstract, interface, virtual, override : ce que les sujets d'examen écrivent en UML ou en Java se traduit mot pour mot.
  • C'est un langage d'entreprise. Applications de bureau (WinForms, WPF), API web (ASP.NET Core), jeux (Unity), applications mobiles (.NET MAUI) : tu le retrouveras en stage et en alternance.

Java, que tu croiseras dans les sujets d'E7, est le cousin de C# : même famille de syntaxe, mêmes concepts. Le chapitre 16 donne les équivalences pour passer de l'un à l'autre.

Installer .NET 10 et ton éditeur

Le langage C# s'exécute sur .NET, la plateforme gratuite et libre de Microsoft. Il te faut le SDK (Software Development Kit), qui contient le compilateur, les bibliothèques et la commande dotnet.

VersionTypeSortieFin du support
.NET 8LTS (support long)novembre 202310 novembre 2026
.NET 10 (C# 14)LTS (support long)11 novembre 202514 novembre 2028
.NET 11 (C# 15)STS (support court, 2 ans)novembre 2026novembre 2028

Le cours utilise .NET 10, la version à support long : c'est celle que les entreprises installent et que tu peux garder pendant tes deux ans de BTS. Télécharge le SDK sur le site officiel dotnet.microsoft.com, puis vérifie l'installation dans un terminal :

dotnet --version
# 10.0.203 (le dernier nombre change à chaque mise à jour de sécurité)

Pour écrire ton code, trois éditeurs gratuits pour un usage étudiant :

ÉditeurSystèmeRemarque
Visual Studio 2026 CommunityWindowsL'environnement complet de Microsoft, gratuit pour les étudiants et les particuliers. Indispensable pour WinForms
Visual Studio Code + extension C# Dev KitWindows, macOS, LinuxLéger ; l'extension ajoute l'explorateur de solutions et le lancement des tests
JetBrains RiderWindows, macOS, LinuxGratuit pour un usage non commercial (études, projets personnels)

Créer et lancer un projet console

Une application console affiche du texte dans un terminal : c'est le meilleur terrain pour apprendre la POO, sans interface graphique pour te distraire. Crée le projet du fil rouge :

bash
dotnet new console -n GestParc.Console
cd GestParc.Console
dotnet run
# Hello, World!

La commande crée un dossier avec deux fichiers utiles :

xml
<!-- GestParc.Console.csproj : la description du projet -->
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net10.0</TargetFramework>
    <ImplicitUsings>enable</ImplicitUsings>
    <Nullable>enable</Nullable>
  </PropertyGroup>
</Project>
csharp
// Program.cs : le point d'entrée
Console.WriteLine("Hello, World!");

Program.cs ne contient ni classe ni méthode Main : depuis C# 9, les instructions de niveau supérieur (top-level statements) te laissent écrire directement le code à exécuter. Le compilateur génère la méthode Main pour toi. ImplicitUsings importe les espaces de noms courants (System, System.Collections.Generic, System.Linq…), et Nullable active le contrôle des valeurs nulles, expliqué plus bas.

Dans Visual Studio, tu obtiens la même chose avec Créer un projet → Application console ; dans VS Code, avec la palette de commandes (.NET: New Project). Le bouton ▶ ou F5 lance le programme.

Variables et types

En C#, chaque variable a un type fixé à la déclaration. Le compilateur vérifie que tu n'y ranges que des valeurs de ce type.

csharp
string numInventaire = "PC-0007";
int anneeAchat = 2023;
decimal prixAchat = 849.90m;
bool enStock = false;
DateOnly dateAchat = new DateOnly(2023, 3, 14);
var marque = "Dell";            // le compilateur déduit le type string

Console.WriteLine($"{numInventaire} ({marque}) acheté le {dateAchat:dd/MM/yyyy} pour {prixAchat:C}");
Console.WriteLine($"En stock : {enStock}, âge : {2026 - anneeAchat} ans");
text
PC-0007 (Dell) acheté le 14/03/2023 pour 849,90 €
En stock : False, âge : 3 ans

Les types que tu utiliseras tout le temps :

TypeContenuExempleValeur par défaut
intEntier de −2 147 483 648 à 2 147 483 647int duree = 45;0
longEntier sur 64 bitslong octets = 5_000_000_000;0
doubleNombre à virgule flottante, environ 15 chiffres significatifsdouble ratio = 0.75;0
decimalNombre décimal exact, 28 chiffres : pour l'argentdecimal prix = 849.90m;0
booltrue ou falsebool actif = true;false
charUn caractère, entre apostropheschar lettre = 'A';'\0'
stringUne chaîne de caractères, entre guillemetsstring nom = "Lambert";null
DateOnlyUne date sans heurenew DateOnly(2026, 11, 2)01/01/0001
DateTimeUne date et une heurenew DateTime(2026, 11, 2, 9, 15, 0)01/01/0001 00:00:00

var demande au compilateur de déduire le type à partir de la valeur. La variable reste typée : var marque = "Dell"; déclare un string, et marque = 12; sera refusé. Utilise var quand le type saute aux yeux (var poste = new Poste(...)), écris le type quand il aide le lecteur.

const déclare une constante connue à la compilation : const int DureeMaxMin = 480;. Par convention, les variables locales s'écrivent en camelCase et les constantes, les classes, les méthodes et les propriétés en PascalCase.

Opérateurs et conversions

Les opérateurs arithmétiques sont ceux de l'algorithmique, avec un piège : la division de deux entiers est une division entière.

csharp
Console.WriteLine(7 / 2);       // 3   : deux int, division entière
Console.WriteLine(7 / 2.0);     // 3,5 : un des deux est un double
Console.WriteLine(7 % 2);       // 1   : le reste (modulo)
OpérateursRôle
+ - * / %Calcul ; + concatène aussi deux chaînes
== != < > <= >=Comparaison, résultat bool
&& || !Et, ou, non logiques (évaluation paresseuse : a && b ne calcule pas b si a est faux)
+= -= *= /= ++ --Raccourcis : total += d; équivaut à total = total + d;
? :Condition en une expression : age >= 5 ? "ancien" : "récent"

Pour convertir un texte en nombre, deux méthodes : int.Parse("12") lève une exception si le texte n'est pas un nombre, int.TryParse renvoie false sans planter. Avec une saisie de l'utilisateur, c'est toujours TryParse :

csharp
string saisie = "12a";
if (int.TryParse(saisie, out int nombre))
{
    Console.WriteLine($"Nombre : {nombre}");
}
else
{
    Console.WriteLine($"« {saisie} » n'est pas un nombre entier");
}
text
« 12a » n'est pas un nombre entier

Entre deux types numériques, la conversion est implicite quand elle ne perd rien (int vers long ou double) et doit être explicite, avec un cast, quand elle peut perdre de l'information : int heures = (int)3.9; donne 3, la partie décimale est tronquée.

Chaînes et interpolation

L'interpolation est la façon moderne de construire un texte : un $ devant les guillemets, des expressions entre accolades. Après un deux-points, tu ajoutes un format.

csharp
string nom = "Diallo";
decimal prix = 1234.5m;
Console.WriteLine($"{prix:C} | {prix:N2} | {prix}");
Console.WriteLine($"[{nom,10}] [{nom,-10}] [{3.14159:0.00}] [{42:000}]");
text
1 234,50 € | 1 234,50 | 1234,5
[    Diallo] [Diallo    ] [3,14] [042]
FormatEffetExemple
:CMonnaie de la culture849,90 €
:N2Nombre à deux décimales, avec séparateur de milliers1 234,50
:0.00 ou :000Gabarit personnalisé3,14, 042
:P0Pourcentage20 %
:dd/MM/yyyyDate14/03/2023
,10 ou ,-10Largeur 10, alignée à droite ou à gaucheutile pour les tableaux en console

Une chaîne est immuable : nom.ToUpper() renvoie une nouvelle chaîne et ne modifie pas nom. Les méthodes que tu utiliseras le plus : Trim(), ToUpper(), ToLower(), Contains(), StartsWith(), Replace(), Split(), Substring(), la propriété Length, et string.IsNullOrWhiteSpace(s) pour tester une saisie vide.

Conditions : if et switch

csharp
int ageAns = 2026 - anneeAchat;
if (ageAns >= 5)
{
    Console.WriteLine("À renouveler");
}
else if (ageAns >= 3)
{
    Console.WriteLine("À surveiller");
}
else
{
    Console.WriteLine("Récent");
}
text
À surveiller

L'expression switch associe une valeur à chaque cas et renvoie un résultat. Le cas _ attrape tout le reste ; s'il manque, le compilateur avertit que des cas ne sont pas traités.

csharp
string priorite = "haute";
int delaiHeures = priorite switch
{
    "critique" => 4,
    "haute" => 8,
    "normale" => 24,
    "basse" => 72,
    _ => throw new ArgumentException($"Priorité inconnue : {priorite}")
};
Console.WriteLine($"Délai pour une priorité {priorite} : {delaiHeures} h");
text
Délai pour une priorité haute : 8 h

L'ancienne instruction switch (priorite) { case "haute": … break; } existe toujours ; tu la croiseras dans du code existant et dans les sujets. Chaque case doit se terminer par break ou return.

Boucles : for, foreach et while

csharp
string[] postes = ["PC-0001", "PC-0002", "PC-0003"];
for (int i = 0; i < postes.Length; i++)
{
    Console.WriteLine($"{i + 1}. {postes[i]}");
}

int[] durees = [30, 45, 20, 90];
int total = 0;
foreach (int d in durees)
{
    total += d;
}
Console.WriteLine($"Total : {total} min, soit {total / 60} h {total % 60} min");
text
1. PC-0001
2. PC-0002
3. PC-0003
Total : 185 min, soit 3 h 5 min
  • for quand tu as besoin de l'indice ;
  • foreach pour parcourir tous les éléments d'un tableau ou d'une collection, sans indice : c'est la boucle que tu écriras le plus en POO ;
  • while (condition) { … } quand le nombre de tours dépend d'une condition, par exemple redemander une saisie tant qu'elle est invalide ; do { … } while (condition); fait au moins un tour.

break sort de la boucle, continue passe directement au tour suivant.

Les crochets ["PC-0001", "PC-0002"] sont une expression de collection (C# 12). Tu verras aussi l'ancienne écriture new string[] { "PC-0001", "PC-0002" }. Un tableau a une taille fixe (postes.Length) ; pour une liste qui grandit, tu utiliseras List<T> au chapitre 6.

Méthodes

Une méthode est un bloc de code nommé, qui reçoit des paramètres et peut renvoyer une valeur. Sa signature indique le type de retour (void s'il n'y en a pas), le nom et la liste des paramètres typés.

csharp
Console.WriteLine(ValeurNette(849.90m, 3, 4));
Console.WriteLine(FormaterDuree(185));
Console.WriteLine(FormaterDuree(45));

static decimal ValeurNette(decimal prix, int ageAns, int dureeAns)
{
    if (ageAns >= dureeAns)
    {
        return 0m;
    }
    return Math.Round(prix * (dureeAns - ageAns) / dureeAns, 2, MidpointRounding.AwayFromZero);
}

static string FormaterDuree(int minutes)
{
    int h = minutes / 60;
    int m = minutes % 60;
    return h > 0 ? $"{h} h {m:00}" : $"{m} min";
}
text
212,48
3 h 05
45 min

Dans Program.cs, les méthodes se déclarent après les instructions de niveau supérieur, avec le mot-clé static. À partir du chapitre suivant, elles vivront dans des classes. Quelques possibilités utiles :

  • Paramètre facultatif : static string Formater(int minutes, bool court = false) ; l'appel Formater(45) prend false.
  • Argument nommé : Formater(45, court: true) rend l'appel lisible.
  • Paramètre out : la méthode renvoie une valeur supplémentaire, comme int.TryParse(saisie, out int nombre).
  • Corps d'expression : une méthode d'une seule expression s'écrit avec => : static int Carre(int x) => x * x;.

Les types nullables

null signifie « pas de valeur ». C'est la source d'erreur la plus courante en programmation objet : appeler une méthode sur null provoque une NullReferenceException à l'exécution. C# t'aide de deux façons.

Pour les types valeur (int, decimal, bool, DateOnly…), un ? autorise null : int? etage = null; signifie « étage inconnu », ce qui est différent de « rez-de-chaussée » (0). La propriété HasValue dit si une valeur est présente.

Pour les types référence (string et toutes tes classes), le réglage <Nullable>enable</Nullable> du projet change les règles : string signifie « jamais null », string? signifie « peut être null ». Le compilateur avertit (CS8600, CS8602) quand tu risques de manipuler un null sans l'avoir vérifié.

csharp
string? telephone = null;
Console.WriteLine(telephone ?? "non renseigné");   // ?? : valeur de repli si null
Console.WriteLine(telephone?.Length);              // ?. : null au lieu de planter
int? etage = null;
Console.WriteLine(etage.HasValue ? $"Étage {etage.Value}" : "Pas de bureau");
etage ??= 0;                                       // ??= : affecte seulement si null
Console.WriteLine(etage);
text
non renseigné

Pas de bureau
0

La deuxième ligne affichée est vide : telephone?.Length vaut null, et Console.WriteLine(null) écrit une ligne vide.

Lire une saisie au clavier

Console.ReadLine() renvoie un string? : null si l'entrée est fermée. Une saisie fiable se fait dans une boucle qui redemande tant que la valeur est invalide.

csharp
int duree;
Console.Write("Durée de l'intervention (min) : ");
while (!int.TryParse(Console.ReadLine(), out duree) || duree <= 0)
{
    Console.Write("Saisis un nombre entier positif : ");
}
Console.WriteLine($"Durée enregistrée : {FormaterDuree(duree)}");

De JavaScript à C# : les équivalences

BesoinJavaScriptC#
Déclarer une variablelet n = 5;int n = 5; ou var n = 5;
Constanteconst TVA = 0.2;const decimal Tva = 0.2m;
Afficherconsole.log(x)Console.WriteLine(x)
Interpoler`Total : ${t}`$"Total : {t}"
Égalité===== (les types sont déjà vérifiés)
Tableau[1, 2, 3]int[] t = [1, 2, 3];
Taillet.lengtht.Length (tableau), liste.Count (liste)
Parcourirfor (const x of t)foreach (var x in t)
Fonctionfunction f(a) { … }static int F(int a) { … }
Fonction fléchéex => x * 2x => x * 2 (une lambda, même syntaxe)
Valeur absentenull ou undefinednull, seulement pour un type nullable
Replia ?? b, a?.ba ?? b, a?.b (identiques)

Exercices

Exercice 1 sur 5 Prédire les affichages Réussi À revoir

Sans exécuter, donne ce qu'affiche chaque ligne.

csharp
Console.WriteLine(7 / 2);
Console.WriteLine(7 / 2.0);
Console.WriteLine(7 % 2);
Console.WriteLine(0.1 + 0.2);
Console.WriteLine(0.1m + 0.2m);
Voir la réponseMasquer la réponse de l'exercice 1
text
3
3,5
1
0,30000000000000004
0,3

7 / 2 divise deux int : le résultat est l'entier 3. Dès qu'un opérande est un double (2.0), la division est décimale. % donne le reste. La quatrième ligne montre l'imprécision du double, qui stocke les nombres en binaire ; le decimal calcule en base 10 et donne 0,3 exactement.

Tu avais trouvé ?

Exercice 2 sur 5 Facturer une intervention Réussi À revoir

Sorbier Logistique refacture certaines interventions aux filiales, au quart d'heure entamé : 50 minutes sont facturées comme 60 minutes. Écris la méthode static decimal CoutIntervention(int minutes, decimal tauxHoraire) qui renvoie le montant dû, et 0 pour une durée nulle ou négative. Donne le résultat pour 50 min à 60 €/h, 61 min à 60 €/h et 15 min à 48 €/h.

Voir la réponseMasquer la réponse de l'exercice 2
csharp
static decimal CoutIntervention(int minutes, decimal tauxHoraire)
{
    if (minutes <= 0)
    {
        return 0m;
    }
    int quarts = (minutes + 14) / 15;     // quart d'heure entamé = quart d'heure dû
    return quarts * tauxHoraire / 4;
}
  • 50 min : (50 + 14) / 15 = 4 quarts d'heure, 4 × 60 / 4 = 60 €.
  • 61 min : (61 + 14) / 15 = 5 quarts d'heure, 5 × 60 / 4 = 75 €.
  • 15 min : 1 quart d'heure, 48 / 4 = 12 €.

L'astuce (minutes + 14) / 15 arrondit au quart d'heure supérieur grâce à la division entière. Math.Ceiling(minutes / 15.0) marche aussi, mais renvoie un double qu'il faut reconvertir.

Tu avais trouvé ?

Exercice 3 sur 5 Les valeurs nulles Réussi À revoir

Donne l'affichage de ce programme.

csharp
string? tel = null;
Console.WriteLine(tel?.Length ?? 0);
int? etage = null;
Console.WriteLine((etage + 1).HasValue);
etage ??= 2;
etage ??= 5;
Console.WriteLine(etage);
Voir la réponseMasquer la réponse de l'exercice 3
text
0
False
2

tel?.Length vaut null puisque tel est nul, et ?? 0 remplace ce null par 0. Un calcul avec un int? nul donne null : etage + 1 n'a pas de valeur. Le premier ??= affecte 2 car etage est nul ; le second ne fait rien, etage ayant maintenant une valeur.

Tu avais trouvé ?

Exercice 4 sur 5 Dérouler une boucle Réussi À revoir

Que vaut total à la fin ?

csharp
int total = 0;
for (int i = 1; i <= 10; i++)
{
    if (i % 3 == 0) { continue; }
    if (i > 8) { break; }
    total += i;
}
Voir la réponseMasquer la réponse de l'exercice 4

total vaut 27. Les multiples de 3 (3, 6, 9) sont sautés par continue, avant le test du break. On ajoute donc 1, 2, 4, 5, 7 et 8 ; à i = 9, le continue passe au tour suivant ; à i = 10, i > 8 déclenche le break. 1 + 2 + 4 + 5 + 7 + 8 = 27.

Tu avais trouvé ?

Exercice 5 sur 5 Corriger les erreurs de compilation Réussi À revoir

Ce code contient quatre erreurs ou avertissements. Trouve-les et corrige-les.

csharp
decimal prix = 849.90;
int quantite = "3";
string? commentaire = null;
Console.WriteLine(commentaire.Length);
if (quantite = 3) { Console.WriteLine("ok"); }
Voir la réponseMasquer la réponse de l'exercice 5
  1. decimal prix = 849.90; : erreur CS0664, un littéral à virgule est un double. Écris 849.90m.
  2. int quantite = "3"; : erreur CS0029, un texte n'est pas un entier. Écris int quantite = 3;, ou int.Parse("3") si la valeur vient d'un texte.
  3. commentaire.Length : avertissement CS8602, déréférencement d'une référence peut-être nulle ; ici, c'est une NullReferenceException certaine. Écris commentaire?.Length ?? 0.
  4. if (quantite = 3) : erreur CS0029, une affectation int n'est pas un bool. Écris if (quantite == 3).

Tu avais trouvé ?

Chapitre terminé !

Fais les 5 exercices avant de passer à la suite : c'est en t'entraînant que tout se fixe.

chapitres
–
de série
–
du cours
–
Chapitre suivant : Classe et objet : la POO expliquéeRevoir le sommaire du cours