C# est un langage de programmation oriente objet. Il permet de developper des applications avec le framework .NET et s’execute sur son framework .NET qui est maintenant disponible sur Windows, Linux et MacOS. Le C# est un langage compile qui est dans la famille des langages C. Il comporte egalement des elements fonctionnels avec des expression lambdas.
Historique du C#
- C# 1 (1999) : Premiere version
- C# 2 (2005) : Generiques, iterateurs
- C# 3 (2007) : Types anonymes, expressions lambdas
- C# 4 (2010) : Arguments optionnels
- C# 5 (2012) : Methodes asynchrones
- C# 6 (2015) : Autoproprietes, interpolation de variables
- C# 7 (2017) : Tuples, fonctions locales
- C# 8 (2019) : .NET Core
- C# 9 (2020) : .NET 5, records
- C# 10 (2021) : .NET 6, chaines interpolees dans les constantes, using global, record structs
- C# 11 (2022) : .NET 7, attributes generiques, membres obligatoires
- C# 12 (2023) : .NET 8, exressions de collections, constructeurs principaux
CoreCLR (Common Language Runtime) depuis .NET Core
Compilation : La compilation du code source C# se fait avec le compilateur .NET nomme Roslyn en un langage de bas niveau le CIL (Common Intermediate Language) qui est langage de programmation de type assembleur normalise par l’ECMA. Le CIL est ensuite convertit en code machine a l’execution. On appelle ce processus le JIT (Just in time). Le code machine (bytecode) est un DLR (dynamic language runtime). Il est stocke dans une cache et est execute lorsqu’on lance le programme. L’assembly CIL peut egalement etre pre-compile. Le processus est dans ce cas AOT (Ahead of time). Le format depuis .NET Core s’appelle R2R (Ready 2 run) lorsqu’on fait un publish. Une compilation R2R se fait specifiquement pour un type d’os tandis que le JIT permet d’etre execute sur different os.
Les executables bibilotheques compiles et lies sont stockes dans des « assemblies » .exe ou .dll. Un assembly contient egalement un manifeste pour les metadonnees. Ils sont dentifies par leur nom, version, culture, token de cle publique.
L’espace de nom (namespace)
L’espace de nom permet d’identifier le module de votre application.
– ex: namespace com.monproramme { class { … } }
– ou namespace com.monprogramme; avant les using depuis C# 10.
Les instructions using
Un instruction using permet de dire qu’on veut utiliser les fonctionnalites a l’interieur de cette biliotheque.
– ex pour utiliser les fonctionnalites de la bibliotheque system : using system;
– si on veut declarer un usins qui s’applique a toute notre application, nous pouvons utiliser le mot cle global : ex global using system;
Les variables primitifs
Les variables primitifs de type valeur (int, bool, struct) sont stockees dans la pile (stack) tandis que les variables crees a partir de classes de type reference (class, String) sont stockees dans le tas (heap) et sa reference (pointeur) vers l’objet est stockee dans la pile. On dit qu’elle genere de l’allocation memoire dans le heap. Le stack a une quantite de memoire limitee mais est beaucoup plus simple a manipuler que le tas qui lui est illimite.
Le ramasse miette (garbage collector)
Le ramasse miette regarde s’il y a des objets dans le heap qui ne sont plus referencees et libere ainsi la memoire.
Les entiers
- int (32 bits)
- long (64 bits)
- uint (non signe 32 bits)
- ulong (non signe 64 bits)
- short (16 bits)
- ushot (non signe 16 bits)
- byte (non signe 8 bits ou 1 octet)
- sbyte (signe 8 bits)
Déclaration d’une variable de type entier : int a = 10;
* int est un alias du type Int32.
Les nombre a virgule flottante (nombre arrondis apres la virgule)
- float (7 octets)
- double (15 octets)
Les nomres a virgule fixe (ils sont plus precis que les nombres a virgule flottante)
- decimal
Un booleen
- bool (true, false)
Chaine de caracteres
- char (1 seul caractere)
- string (1 ou plus caracteres)
On peut convertir des variables d’un type a un autre type.
Les types complexes
Un type complexe est toute classe/struct qui ne fait pas partie des types primitifs.
Lorsqu’on assigne une classe existante a une variable, on copie la reference de la classe dans la variable. On a une seule instance de l’objet avec 2 variables qui pointent dessus et non 2 objets separees.
Lorsqu’on assigne une struct existante a un variable, on copie la struc existante dans la variable. On a ainsi 2 objets differentes independantes l’une de l’autre.
Les collections et les generiques
Il existe plusieurs facons de declarer une collection :
- Tableau : On le declare avec les []. On doit connaitre la grandeur du tableau lorsqu’on declare le tableau.
- string[] letters = { « A », « B », « C » }
- ArrayList : On le declare avec new ArrayList(). Cependant, la liste n’est pas type et on a plus de chance de faire une erreur.
- List<type> : On le declare avec new List<type>() en definissant le type de la liste entre <>.
- HashSet<type> : Une liste qui permet de faire une recherche rapide d’un element de la liste.
- Dictionnary<type, type2> : Une liste de cles / valeurs
Covariance et contravarience : Generique Out et In et Action
HashSet et GetHashCode : Une collection de type HashSet indexe ses elements grace a la methode GetHashCode implemente dans la classe du type d’objets de la liste.
Un Dictionnary<keyType, valueType> est un mix de hashset et de list qui permet d’avoir une liste de paires de cle/valeur. Un type tres efficace pour la recherche.
Il existe d’autres listes qui facilite les manipulations d’ajout et de retrait d’un element de la liste :
- Stack : Une pile (LIFO – last in first out)
- Queue : Une file d’attente (FIFO – first in first out)
- LinkedList : Une liste chainee (permet d’ajouter ou de retirer un element des 2 bords de la liste)
Une collection triee : SortedSet<type>
Les generiques
On peut creer des methodes generiques (method<t>(T x)) et des classes generiques (class name<t>).
Values Types (stored in the stack) :
Les 5 types de bases (simple value types, des alias/keywods des types .NET) :
- char : character
- string : alphanumeric data for presentation not calculation. string est du type reference.
- int : integer System.Int32
- float, double, decimal : floating point. double is used as default. 0.25f for float. 0.25m for decimal.
- bool : boolean (true/false)
References Types (stored in the heap) :
- Arrays, classes, strings
Exemple de codes :
Console.WriteLine(« Hello World! »); // Affiche « Hello World! » dans la console.
Références :