C# est destiné à développer sur la plateforme.NET, unepile technologique créée par Microsoft pour succéder àCOM.
Lesexécutables en C# sont subdivisés enassemblies, ennamespaces, en classes et en membres de classe[4]. Un assembly est la formecompilée, qui peut être un programme (un exécutable) ou une bibliothèque de classes (unedll). Un assembly contient le code exécutable enCIL, ainsi que les symboles. Le codeCIL est traduit enlangage machine au moment de l'exécution par la fonctionjust-in-time de la plateforme .NET[4].
leCommon Language Runtime (abr. CLR) est leruntime utilisé par les langages de la plateforme .NET (C#,Visual Basic .NET,J#, etc.), les services fournis par la CLR sont le lancement et l'exécution de programmes, leramasse-miettes et lagestion d'exceptions. Un programme pour la plateforme .NET est tout d'abord compilé en une forme intermédiaire, leCIL, puis ce code CIL est transformé en code machine qui sera exécuté par la CLR. Ce code machine est appelémanaged code parce que son exécution est sous le contrôle de la CLR[2].
Un autre produit de la plateforme .NET est l'environnement de développementVisual Studio .NET, outil généralement utilisé pour programmer en C#[2].
Le typage sûr signifie notamment que les opérations suivantes sont refusées : utilisation de variable noninitialisée, tentative d'accéder au-delà des limites d'un tableau,conversions de type dont les résultats ne sont pas prévisibles,dépassement des limites lors d'opérations arithmétiques[2].
Beaucoup de possibilités deJava se retrouvent dans C# et il y a une forte ressemblance entre un code écrit en C# et le code équivalent en Java[2].
Les struct sont similaires aux classes, mais ce sont des types valeurs et ils ne peuvent pas êtrehérités[4].
delegate
Un delegate est une référence à une méthode qui comporte certainsparamètres. Les delegates permettent d'assigner des méthodes à des variables et les passer en paramètre[4].
enum
Un type énuméré est un type valeur qui comporte un lot de constantes. Chaque type énuméré a un type sous-jacent : un type primitif déterminé en fonction des valeurs des constantes.
type nullable
Les nullable sont des types primitifs qui peuvent en plus avoir la valeurnull[4]. Chaque type primitif T a un type nullable associé T?. Par exemple une variable de type int? peut contenir un int ou null[4].
Le langage compte un certain nombre de changements par rapport auC/C++ ; on notera particulièrement les points suivants :
la manipulation directe depointeurs ne peut se faire qu’au sein d’un code marquéunsafe, et seuls les programmes avec les permissions appropriées peuvent exécuter des blocs de codeunsafe. La plupart des manipulations de pointeurs se font via des références sécurisées, dont l’adresse ne peut être directement modifiée, et la plupart des opérations de pointeurs et d’allocations sont contrôlées contre les dépassements de mémoire. Les pointeurs ne peuvent pointer que sur destypes de valeurs, les typesobjets, manipulés par leramasse-miettes, ne pouvant qu’être référencés ;
les objets ne peuvent pas être explicitement détruits. Leramasse-miettes s’occupe de libérer la mémoire lorsqu’il n’existe plus aucune référence pointant sur un objet. Toutefois, pour les objets gérant des types non managés, il est possible d’implémenter l’interfaceIDisposable pour spécifier des traitements à effectuer au moment de la libération de la ressource ;
l’héritage multiple de classes est interdit, mais une classe peut implémenter un nombre illimité d’interfaces, et une interface peut hériter de plusieurs interfaces ;
le C# est beaucoup plustypé que le C++ ; les seules conversions implicites sont celles entre les différentes gammes d’entiers et celles d’un type dérivé à un type parent. Aucune conversion implicite n’a lieu entre booléens et entiers, entre membres d’énumération et entiers, ni de pointeurs sur un typevoid (quoique pour ce dernier point l’utilisation de références sur le type Object permette d’obtenir le même effet). Les conversions définies par l’utilisateur peuvent être définies comme implicites ou explicites ;
la syntaxe pour la déclaration destableaux n’est pas la même :int[] a = new int[5] remplaceint a[5]. Car il s'agit d'uneallocation dynamique,int[] a étant la déclaration d'une référence (nulle si non initialisée). L'allocation manuelle d'un tableau sur la pile reste cependant possible avec le mot cléstackalloc[8] ;
les membres d’une énumération sont rassemblés dans leur propreespace de noms ;
le C# ne gère pas lestemplates, mais cette fonctionnalité a été remplacée par lestypes génériques apparus avec C# 2.0 ;
les propriétés ont été introduites, et proposent une syntaxe spécifique pour l’accès aux données membres (ainsi que la facilitation de l’accès simultané par plusieursthreads) ;
Java a des exceptions vérifiées, alors que les exceptions du C# ne sont pas vérifiées, comme en C++ ;
Java permet la génération automatique de la documentationHTML à partir des fichiers sources à l'aide des descriptionsJavadoc-syntax, tandis que le C# utilise des descriptions fondées sur leXML ;
C# prend en charge les indexeurs, les méthodes déléguées, et les événements (là où Java se contente dupatron de conceptionobservateur) ;
C# ne prend pas en charge les implémentations anonymes d'interfaces et de classes abstraites ;
C# ne prend en charge que les classes internes statiques ;
C# prend en charge les structures en plus des classes (les structures sont des typesvaleur : on stocke le contenu et non l'adresse) ;
C# utilise une syntaxe intégrée au langage (DllImport[9]) et portable pour appeler une bibliothèque native, tandis que Java utiliseJava Native Interface ;
C# intègre lagénéricité et la machine.NET a été modifiée pour permettre cela (Java l'intègre également, mais son implémentation a été réalisée dans le compilateurjavac sans changer lebytecode Java)[10].
C'est en septembre 2002 que laplateforme .NET et C# sont présentés au public[2]. C# devient le langagede facto de cette plateforme, il a par ailleurs été utilisé pour implémenter une partie de la plateforme .NET[2].
Microsoft mit à disposition du public en, après une longue période de beta-tests, la version 2.0 de la bibliothèque .NET, accompagnée d’une nouvelle version de la quasi-totalité des outils associés. C# ne fait pas exception à la règle et sort donc en version 2.0, avec les ajouts suivants :
les classes partielles, permettant de répartir l’implémentation d’une classe sur plusieurs fichiers ;
lestypes génériques, qui ne sont pas une simple copie destemplates C++. Par exemple, on trouvera dans les génériques C# la restriction de types (pour spécifier les types utilisables dans une généralisation). Par contre, il est impossible d’utiliser des expressions comme paramètres pour la généralisation ;
un nouvel itérateur qui permet l’utilisation decoroutines via le mot-cléyield, équivalent duyield que l’on trouve enPython ;
les méthodes anonymes avec des règles defermeture configurables ;
les types « nullables », c'est-à-dire la possibilité de spécifier qu’un type de valeur peut être nul. Ceux-ci sont déclarés avec le caractère point d'interrogation « ? » suivant le nom du type, comme ceci :int? i = null;
le nouvel opérateur double point d'interrogation « ?? » utilise deux opérandes et retourne le premier non nul. Il a été introduit pour spécifier une valeur par défaut pour les types « nullables ».
À titre de référence, les spécifications complètes des nouveautés introduites dans la version 2.0 sont disponibles dans lesliens externes.
La fonctionnalité des types nullables fut corrigée quelques semaines seulement avant la sortie publique de la version 2.0, car il a été mis en lumière que si la valeur de la variable était bien nulle, cette variable n’était pas nulle au sens traditionnel du terme, c'est-à-dire qu’il ne s’agit pas d’une référence vide. Ainsi, la conversion d’un type primitif de valeur nulle en objet donnait une référence non nulle vers une valeur nulle. Il fallut donc, pour corriger ce problème, corriger le noyau duCLR et effectuer de nombreuses vérifications et corrections sur tous les produits de la gamme .NET 2.0 (Visual Studio 2005,SQL Server 2005, C# et VB.NET).
Le C# 3.0 fut présenté au salonProcessing Community Day[11] 2005. La version finale est disponible depuis le au téléchargement sur le site de Microsoft][12]. Les principales nouveautés sont les suivantes :
L’ajout des mots-clefsselect,from etwhere pour permettre la formation et l’exécution de requêtes SQL, XML, ou directement sur descollections. Cette fonctionnalité fait partie du programme Language Integrated Query (LINQ)][13].
Nouvelle possibilité d’initialisation d'un objet : À la place deClient c = new Client(); c.Nom = "Dupont";, on peut utiliserClient c = new Client{ Nom = "Dupont" };
Inférence du type des variables locales :string s = "Dupont" peut être remplacé parvar s = "Dupont"
Introduction des types anonymes :var x = new { Nom = "Dupont" } peut être utilisé à la place declass __anonymous { private string _nom; public string Nom { get { return _nom; } set { _nom = value; } } } __anonymous x = new __anonymous(); x.Nom = "Dupont";
Les arbres d'expressions (expression trees[14]) : permettent la compilation du code sous forme d'arbres d'objets facilement analysables et manipulables.
Méthodes étendues : permet d'ajouter des méthodes à une classe en y ajoutant un premier paramètrethis.
Le code compilé en C# 3.0 est entièrement compatible avec celui du 2.0, étant donné que les améliorations apportées ne sont que purement syntaxiques ou ne consistent qu’en des raccourcis compensés au moment de la compilation. Les nouveautés introduites dans les bibliothèques de la version 3.5 (LINQ, etc.) ne sont cependant pas utilisables avec les versions précédentes de C#.
Laversion 5 du langage permet de programmer plus simplement des programmes asynchrones grâce à l'ajout des mots clésasync etawait.
Le comportement desclosures dans la boucleforeach(en) a été modifié. Il n'est désormais plus nécessaire d'introduire une variable locale dans une boucleforeach pour éviter les problèmes declosure[19].
À noter également les informations relatives à l'appelant[20] permettant de connaître le nom de la méthode qui a appelé une propriété.
La sixième version du C# apporte plusieurs modifications, notamment :
Les propriétés implémentées automatiquement (ou propriétés automatiques) sont apparues en C# 3, pour simplifier la déclaration de propriétés qui se contentent d'encapsuler l'accès à des champs. Bien qu'elles permettent de rendre le code plus concis, elles présentent un inconvénient : il n'est pas possible de les initialiser au niveau de la déclaration, il faut forcément le faire dans le constructeur. De plus, il n'est pas possible de faire des propriétés automatiques en lecture seule, puisqu'elles n'ont pas de mutateur (setter) et on ne pourrait donc pas leur affecter de valeur.
C# 6 remédie à ce problème en permettant d'initialiser les propriétés automatiques au niveau de la déclaration[21].
La version 7 du langage apporte de nombreuses nouveautés dont les principales sont[22]:
Les fonctions locales: la possibilité de déclarer une méthode à l'intérieur dans une autre méthode
Tuples et déconstruction: cela permet par exemple pour une fonction, de renvoyer plusieurs valeurs
Variables out: une variable peut être déclaré au moment de l'appel. Par exemple:
int.TryParse(s,outinti);
Pattern matching (oufiltrage par motif en français) permet de déterminer si une valeur correspond à un motif donné. Exemple avec un switch[23] :
switch(shape){caseRectangler:Console.WriteLine($"Rectangle with area {r.Width * r.Height}");break;caseCirclecwhenc.Radius<5:Console.WriteLine($"Small circle");break;caseCirclec:Console.WriteLine($"Large circle");break;}
publicvoidUseDisposableObject(){usingvardisposableObject=newDisposableObject();// Utilisation de disposableObject// ...// disposableObject.Dispose() est exécuté juste avant la sortie de la méthode}
La version 14 de C# apporte les principales nouveautés[32]:
le mot cléfield pour faciliter l'écriture des propriétés
l'amélioration sur la déclaration des lambda (paramètres avec modificateurs commeout)
l'affectation conditionnelle en cas de null. Il est possible d'utiliser?. pour affecter une propriété sans avoir à tester sa nullité, comme dans l'exemple suivant:
Le standard ECMA 334 et l'ISO 23270 définissent le nom du langage comme le caractèreUnicode 0043 (C majuscule) suivi du caractère 0023 (#)[34]. Il est prononcé « C sharp » et non « C hash », « sharp » désignant en effet le symbole musical♯ mais # étant nécessaire pour un accès facile depuis un clavier d'ordinateur qui propose lecroisillon (« hash ») à la place.
Le nom "C#" est inspiré de la notation musicale où un dièse indique que la note écrite doit être augmentée d'un demi-ton. Ceci est similaire au nom de langage de C++, où "++" indique qu'une variable doit être incrémentée de 1 après avoir été évaluée. Le symbole # ressemble également à une ligature de quatre symboles "+" (dans une grille deux par deux), ce qui implique que le langage est un incrément de C++[réf. souhaitée].