Module : Programmation .net C#
Niveau : 4ème Génie Informatique (Spécialité Data Science)
Prérequis : TP1 (Fondamentaux) validé
Dans le TP1, vous avez manipulé la syntaxe de base pour créer une application console simple. Ce chapitre a pour but de formaliser ces connaissances et de "lever le capot" : comprendre comment votre code C# est structuré, compilé et géré en mémoire.
dotnet run au Processeur : Architecture .NETContrairement au C++ (compilé directement en code machine) ou au Python (interprété), C# utilise un modèle hybride :
.dll ou
.exe.Figure 1 : Le chemin de compilation C#
Note : Ce modèle garantit que le même binaire tourne sur Windows et Linux, tout en offrant des performances proches du C++ grâce aux optimisations du JIT.
Les programmes modernes (C# 10+) ne nécessitent plus d'écrire explicitement
public static void Main. Le code écrit directement dans Program.cs est
automatiquement encapsulé dans le point d'entrée Main par le compilateur.
En C#, tout hérite ultimement de System.Object. Pour un développeur, la
distinction critique n'est pas "texte vs nombre", mais Stack vs Heap (Lieu de stockage).
| Type C# | Type .NET (CTS) | Famille (Stockage) | Usage en Data Science |
|---|---|---|---|
int |
System.Int32 |
Valeur (Stack) | Entiers standard (Index, Compteurs). |
long |
System.Int64 |
Valeur (Stack) | Grands entiers (Big Data, IDs BDD). |
double |
System.Double |
Valeur (Stack) | Calculs scientifiques (virgule flottante IEEE 754). |
decimal |
System.Decimal |
Valeur (Stack) | Finance (128 bits, haute précision, pas d'erreurs d'arrondi). |
bool |
System.Boolean |
Valeur (Stack) | Logique (true/false). |
char |
System.Char |
Valeur (Stack) | Un caractère Unicode (16 bits). |
DateTime |
System.DateTime |
Valeur (Stack) | Gestion du temps (Struct). Indispensable pour les séries temporelles. |
string |
System.String |
Référence (Heap) | Texte. Attention : Stocké comme un objet (Pointeur). |
Pour simplifier, imaginez votre mémoire RAM divisée en deux zones distinctes :
C'est votre "Plan de travail personnel".
int,
double, bool).C'est un "Grand Entrepôt" distant.
Class, String, List).string : Le Faux AmiLe type string est un Type Référence (stocké sur la Heap), mais il est
immuable (Immutable).
string s = "A";
s += "B"; // CECI NE MODIFIE PAS L'OBJET !
// Cela crée un NOUVEL objet "AB" en mémoire et change le pointeur.
// L'ancien "A" devient un déchet pour le Garbage Collector.
+.StringBuilder ou l'interpolation $"..." qui sont
optimisés.La classe est le plan (blueprint) de vos objets. Analysons sa structure en détail.
public class Sensor
{
// 1. Champs (Attributs)
private int _internalId; // Utilisation de l'underscore en préfixe
// 2. Propriétés (Properties)
public string Name { get; set; }
// 3. Constructeur
public Sensor(int id, string name) { ... }
// 4. Méthodes
public void Calibrate() { ... }
}
Contrairement au Java ou au Python, C# est très strict sur les conventions pour distinguer ce qui est public de ce qui est privé :
MySensor, GetValue): Utilisé pour les
Classes, les Propriétés et les Méthodes (tout ce
qui est Public).mySensor, id): Utilisé pour les
variables locales et les paramètres._internalId): Utilisé pour les champs
privés (attributs), pour les différencier des variables locales.Ce sont les variables déclarées directement dans la classe.
_internalId).C'est la différence majeure avec Java ou C++. Une propriété expose une donnée tout en gardant le contrôle (encapsulation). Voici les 4 formats essentiels à connaître :
C'est la forme la plus courante (90% des cas). Le compilateur crée le champ privé
(backing field) pour vous. Idéal pour les DTOs (Data Transfer Objects).
public string Name { get; set; }
// Read: var n = obj.Name;
// Écriture : obj.Name = "Sonde 1";
Utilisée quand vous devez contrôler la valeur avant de l'assigner (ex: empêcher une température < -273). Nécessite de déclarer le champ privé manuellement.
private double _value; // Champ de stockage (camelCase avec prefixe _)
public double Value
{
get { return _value; }
set
{
// Le mot clé 'value' représente la donnée entrante
if (value < -273.15)
Console.WriteLine("Erreur physique !");
else
_value = value;
}
}
Très puissante en Data Science. Cette propriété ne stocke rien en mémoire. Elle calcule le résultat à la volée à chaque appel. C'est une méthode déguisée en propriété (Lecture seule).
public double Price { get; set; }
public double TaxRate { get; set; }
// Syntaxe '=>' (Expression Lambda)
// Pas de 'set'. La valeur change si Price ou TaxRate changent.
public double TotalCost => Price * (1 + TaxRate);
Essentiel pour la programmation robuste. Permet de définir la valeur uniquement à la création de l'objet. Ensuite, elle devient lecture seule.
public int Id { get; init; }
// Usage :
var s = new Sensor { Id = 101 }; // OK (Initialisation)
// s.Id = 102; // ERREUR DE COMPILATION ! (Modification interdite)
Méthode spéciale appelée à l'instanciation (new).
this permet de lever l'ambiguïté entre les paramètres et les membres de
la classe.public Sensor(string name)
{
this.Name = name; // 'this.Name' est la propriété, 'name' est le paramètre
}
Ce sont les comportements de l'objet. Le nom est toujours en PascalCase.
// Méthode simple (Action)
public void Calibrate()
{
Console.WriteLine($"Calibrating {Name}...");
Value = 0.0;
}
// Surcharge (Overloading) : Même nom, signature différente
public void Calibrate(double offset)
{
Value += offset;
}
// Méthode avec valeur de retour
public bool IsCritical()
{
return Value > 80.0;
}
Classique, identique au C/C++/Java.
if (temperature > 100) {
Alert();
} else if (temperature < 0) {
Freeze();
} else {
Ok();
}
C# a considérablement modernisé le switch statement.
// Switch Classique
switch (sensorType)
{
case "CO2":
ProcessGas();
break;
default:
ProcessOther();
break;
}
// Switch Expression (Modern C# - Widely used in Data)
// More concise, returns a value directly.
string category = temperature switch
{
> 30 => "Hot",
< 10 => "Cold",
_ => "Normal" // '_' est le cas par défaut (default)
};
Utilisée quand on connaît le nombre d'itérations ou qu'on a besoin de l'index i.
for (int i = 0; i < sensors.Count; i++)
{
Console.WriteLine(sensors[i].Name);
}
Utilisée quand la condition d'arrêt dépend d'un état et non d'un compteur.
while (sensor.IsActive())
{
sensor.ReadData();
}
C'est la boucle la plus utilisée en C#. Elle parcourt n'importe quelle collection (List,
Array, etc.) du début à la fin.
var fleet = new List<Sensor>();
// ... remplissage ...
foreach (var s in fleet)
{
// 's' est une variable locale représentant l'élément courant
Console.WriteLine(s.Value);
}
string est un
Reference Type !public int a;).
Utilisez toujours des propriétés (public int A { get; set; }) pour respecter
l'encapsulation .NET.foreach pour lire des données et les
switch expressions pour catégoriser des valeurs (Data Cleaning).Module: .NET C# Programming
Level: 4th Year Computer Engineering (Data Science Specialty)
Prerequisite: TP1 (Fundamentals) validated
In TP1 (Lab 1), you handled basic syntax to create a simple console application. This chapter aims to formalize this knowledge and "lift the hood": understanding how your C# code is structured, compiled, and managed in memory.
dotnet run to Processor: .NET ArchitectureUnlike C++ (compiled directly into machine code) or Python (interpreted), C# uses a hybrid model:
.dll or
.exe file.Figure 1: The C# Compilation Path
Note: This model ensures that the same binary runs on Windows and Linux while offering performance close to C++ thanks to JIT optimizations.
Modern programs (C# 10+) no longer require explicitly writing public static void Main. The code
written directly in Program.cs is automatically encapsulated in the Main entry
point by the compiler.
In C#, everything ultimately inherits from System.Object. For a developer, the
critical distinction isn't "text vs number", but Stack vs Heap (Storage Location).
| C# Type | .NET Type (CTS) | Family (Storage) | Usage in Data Science |
|---|---|---|---|
int |
System.Int32 |
Value (Stack) | Standard integers (Index, Counters). |
long |
System.Int64 |
Value (Stack) | Large integers (Big Data, DB IDs). |
double |
System.Double |
Value (Stack) | Scientific calculations (IEEE 754 floating point). |
decimal |
System.Decimal |
Value (Stack) | Finance (128 bits, high precision, no rounding errors). |
bool |
System.Boolean |
Value (Stack) | Logic (true/false). |
char |
System.Char |
Value (Stack) | A Unicode character (16 bits). |
DateTime |
System.DateTime |
Value (Stack) | Time management (Struct). Essential for time series. |
string |
System.String |
Reference (Heap) | Text. Warning: Stored as an object (Pointer). |
To simplify, imagine your RAM memory divided into two distinct zones:
This is your "Personal Workbench".
int,
double, bool).This is a distant "Large Warehouse".
Class,
String, List).string: The False FriendThe string type is a Reference Type (stored on the Heap), but it is
immutable.
string s = "A";
s += "B"; // THIS DOES NOT MODIFY THE OBJECT!
// This creates a NEW object "AB" in memory and changes the pointer.
// The old "A" becomes garbage for the Garbage Collector.
+.StringBuilder or interpolation $"..." which are
optimized.The class is the blueprint of your objects. Let's analyze its structure in detail.
public class Sensor
{
// 1. Fields (Attributes)
private int _internalId; // Using underscore prefix
// 2. Properties
public string Name { get; set; }
// 3. Constructor
public Sensor(int id, string name) { ... }
// 4. Methods
public void Calibrate() { ... }
}
Unlike Java or Python, C# is very strict about conventions to distinguish public from private members:
MySensor, GetValue): Used for
Classes, Properties, and Methods (everything
Public).mySensor, id): Used for local
variables and parameters._internalId): Used for private fields
(attributes), to differentiate them from local variables.These are variables declared directly inside the class.
_internalId).This is the major difference with Java or C++. A property exposes data while keeping control (encapsulation). Here are the 4 essential formats to know:
This is the most common form (90% of cases). The compiler creates the private field
(backing field) for you. Ideal for DTOs (Data Transfer Objects).
public string Name { get; set; }
// Read: var n = obj.Name;
// Write: obj.Name = "Probe 1";
Used when you need to control the value before assigning it (e.g., preventing a temperature < -273). Requires declaring the private field manually.
private double _value; // Storage field (camelCase with _ prefix)
public double Value
{
get { return _value; }
set
{
// The keyword 'value' represents the incoming data
if (value < -273.15)
Console.WriteLine("Physics Error!");
else
_value = value;
}
}
Very powerful in Data Science. This property stores nothing in memory. It calculates the result on the fly at each call. It is a method disguised as a property (Read-only).
public double Price { get; set; }
public double TaxRate { get; set; }
// Syntax '=>' (Lambda Expression)
// No 'set'. Value changes if Price or TaxRate changes.
public double TotalCost => Price * (1 + TaxRate);
Essential for robust programming. Allows setting the value only at object creation. Afterward, it becomes read-only.
public int Id { get; init; }
// Usage:
var s = new Sensor { Id = 101 }; // OK (Initialization)
// s.Id = 102; // COMPILATION ERROR! (Modification forbidden)
Special method called at instantiation (new).
this keyword allows resolving ambiguity between parameters and class members.
public Sensor(string name)
{
this.Name = name; // 'this.Name' is the property, 'name' is the parameter
}
These are the object's behaviors. The name is always in PascalCase.
// Simple Method (Action)
public void Calibrate()
{
Console.WriteLine($"Calibrating {Name}...");
Value = 0.0;
}
// Overloading: Same name, different signature
public void Calibrate(double offset)
{
Value += offset;
}
// Method with return value
public bool IsCritical()
{
return Value > 80.0;
}
Classic, identical to C/C++/Java.
if (temperature > 100) {
Alert();
} else if (temperature < 0) {
Freeze();
} else {
Ok();
}
C# has significantly modernized the switch statement.
// Switch Classique
switch (sensorType)
{
case "CO2":
ProcessGas();
break;
default:
ProcessOther();
break;
}
// Switch Expression (Modern C# - Widely used in Data)
// More concise, returns a value directly.
string category = temperature switch
{
> 30 => "Hot",
< 10 => "Cold",
_ => "Normal" // '_' is the default case
};
Used when you know the number of iterations or need the index i.
for (int i = 0; i < sensors.Count; i++)
{
Console.WriteLine(sensors[i].Name);
}
Used when the stop condition depends on a state rather than a counter.
while (sensor.IsActive())
{
sensor.ReadData();
}
This is the most used loop in C#. It iterates through any collection (List,
Array, etc.) from start to finish.
var fleet = new List<Sensor>();
// ... filling ...
foreach (var s in fleet)
{
// 's' is a local variable representing the current element
Console.WriteLine(s.Value);
}
string is a
Reference Type!public int a;). Always
use properties (public int A { get; set; }) to respect .NET encapsulation.foreach for reading data and
switch expressions for categorizing values (Data Cleaning).