Histoire du langage C#

Cet article fournit un historique de chaque version majeure du langage C#. L’équipe C# continue d’innover et d’ajouter de nouvelles fonctionnalités. L’état détaillé des fonctionnalités de langage, notamment celles prises en compte pour les versions à venir, est disponible dans le dépôt dotnet/roslyn sur GitHub.

Important

Le langage C# s’appuie sur des types et des méthodes dans ce que la spécification C# définit comme une bibliothèque standard pour certaines fonctionnalités. La plateforme .NET fournit ces types et ces méthodes dans des packages. Par exemple, le traitement des exceptions. Chaque instruction ou expressionthrow est vérifiée pour s’assurer de l’objet levé est dérivé de Exception. De même, chaque catch est vérifié pour assurer que le type intercepté est dérivé de Exception. Chaque version peut ajouter de nouvelles spécifications. Pour utiliser les dernières fonctionnalités de langage dans les environnements plus anciens, vous devrez peut-être installer des bibliothèques spécifiques. Ces dépendances sont décrites dans la page pour chaque version spécifique. Pour en savoir plus, consultez les relations entre le langage et la bibliothèque pour l’arrière-plan sur cette dépendance.

C# version 12

Publication : novembre 2023

Les fonctionnalités suivantes ont été ajoutées dans C# 12 :

  • Constructeurs principaux : vous pouvez créer des constructeurs principaux dans n’importe quel type de class ou de struct.
  • Expressions de collection : nouvelle syntaxe permettant de spécifier des expressions de collection, y compris l’opérateur de propagation (..), pour développer n’importe quelle collection.
  • Tableaux inline : permettent à un développeur de créer un tableau de taille fixe dans un type de struct.
  • Paramètres facultatifs dans les expressions lambda : vous pouvez définir des valeurs par défaut pour les paramètres sur les expressions lambda.
  • Paramètres ref readonly - Les paramètres ref readonly permettent une plus grande clarté pour les API qui utilisent potentiellement des paramètres ref ou in.
  • Alias pour tous types : vous pouvez utiliser la directive d’alias using afin de créer un alias pour n’importe quel type, plutôt que juste pour des types nommés.
  • Attribut expérimental : indiquez une fonctionnalité expérimentale.

Et Intercepteurs : publiée en tant que Fonctionnalité d’évaluation.

Dans l’ensemble, C# 12 fournit de nouvelles fonctionnalités qui font que votre écriture de code C# soit plus productive. La syntaxe que vous connaissiez déjà est disponible à d’autres endroits. Une autre syntaxe active la cohérence pour les concepts connexes.

C# version 11

Publication : novembre 2022

Les fonctionnalités suivantes ont été ajoutées dans C# 11 :

C# 11 introduit des mathématiques génériques et plusieurs fonctionnalités qui prennent en charge cet objectif. Vous pouvez écrire des algorithmes numériques une fois pour tous les types de nombres. Il existe d’autres fonctionnalités pour faciliter l’utilisation des types struct, comme les membres requis et les structs par défaut automatique. L’utilisation de chaînes est plus facile avec les littéraux de chaîne bruts, la nouvelle ligne dans les interpolations de chaîne et les littéraux de chaîne UTF-8. Les fonctionnalités telles que les types locaux de fichiers permettent aux générateurs sources d’être plus simples. Enfin, les modèles de liste ajoutent davantage de prise en charge pour la mise en correspondance des modèles.

C# version 10

Publication : novembre 2021

C# 10 ajoute les fonctionnalités et améliorations suivantes au langage C# :

D’autres fonctionnalités étaient disponibles en mode préversion. Pour utiliser ces fonctionnalités, vous devez définir <LangVersion> sur Preview dans votre projet :

C# 10 continue de travailler sur des thèmes de suppression de cérémonie, de séparation des données à partir d’algorithmes et d’amélioration des performances pour le runtime .NET.

La plupart des fonctionnalités permettent de taper moins de code pour exprimer les mêmes concepts. Les structs d’enregistrement synthétisent la plupart des mêmes méthodes que les classes d’enregistrement. Les structs et les types anonymes prennent en charge les expressions. Directives à utilisation globale et déclarations d’espace de noms délimitées par des fichiers signifient que vous exprimez plus clairement les dépendances et l’organisation de l’espace de noms. Les améliorations lambda facilitent la déclaration d’expressions lambda là où elles sont utilisées. Les nouveaux modèles de propriétés et les améliorations de la déconstruction créent du code plus concis.

Les nouveaux gestionnaires de chaînes interpolés et le comportement AsyncMethodBuilder peuvent améliorer les performances. Ces fonctionnalités de langage ont été appliquées dans le runtime .NET pour obtenir des améliorations des performances dans .NET 6.

C# 10 marque également plus d’un passage à la cadence annuelle pour les versions de .NET. Étant donné que toutes les fonctionnalités ne peuvent pas être effectuées sur une période annuelle, vous pouvez essayer quelques fonctionnalités « préversion » en C# 10. Les attributs génériques et les membres abstraits statiques dans les interfaces peuvent être utilisés, mais ces fonctionnalités d’évaluation peuvent changer avant leur version finale.

C# version 9

Publication : novembre 2020

C# 9 a été publié avec .NET 5. Il s’agit de la version du langage par défaut pour n’importe quel assembly qui cible la version .NET 5. Il contient les fonctionnalités nouvelles et améliorées suivantes :

C# 9 poursuit trois des thèmes des versions précédentes : la suppression de cérémonie, la séparation des données des algorithmes et la fourniture de modèles supplémentaires dans d’autres endroits.

Les instructions de niveau supérieur signifient que votre programme principal est plus simple à lire. Le besoin de cérémonie est moins important : un espace de noms, une classe Program et static void Main() sont tous inutiles.

L’introduction de records fournit une syntaxe concise pour les types de référence qui suivent la sémantique des valeurs pour l’égalité. Vous utilisez ces types pour définir des conteneurs de données qui définissent généralement un comportement minimal. Les setters à init seul offrent la possibilité de mutation non destructrice (expressions with) dans les enregistrements. C# 9 ajoute également des types de retour covariants afin que les enregistrements dérivés puissent remplacer les méthodes virtuelles et retourner un type dérivé du type de retour de la méthode de base.

Les fonctionnalités de critères spéciaux ont été développées de plusieurs façons. Les types numériques prennent désormais en charge les modèles de plage. Les modèles peuvent être combinés à l’aide de modèles and, or et not. Des parenthèses peuvent être ajoutées pour clarifier des modèles plus complexes :

C# 9 inclut de nouvelles améliorations de correspondance de modèle :

  • Les modèles de type correspondent à un objet qui correspond à un type particulier
  • Les modèles entre parenthèses appliquent ou mettent en évidence la priorité des combinaisons de modèles
  • Les modèles conjonctifs and nécessitent que les deux modèles correspondent
  • Les modèles disjonctifs or nécessitent une correspondance entre les deux modèles
  • Les modèles non validés not nécessitent qu’un modèle ne corresponde pas
  • Les modèles relationnels nécessitent que l’entrée soit inférieure, supérieure, inférieure ou égale, ou supérieure ou égale à une constante donnée

Ces modèles enrichissent la syntaxe des modèles. Prenons les exemples suivants :

public static bool IsLetter(this char c) =>
    c is >= 'a' and <= 'z' or >= 'A' and <= 'Z';

L’ajout de parenthèses facultatives indique clairement que and a une priorité plus élevée que or :

public static bool IsLetterOrSeparator(this char c) =>
    c is (>= 'a' and <= 'z') or (>= 'A' and <= 'Z') or '.' or ',';

L’une des utilisations les plus courantes est une nouvelle syntaxe pour une vérification null :

if (e is not null)
{
    // ...
}

L’un de ces modèles peut être utilisé dans n’importe quel contexte où les modèles sont autorisés : expressions de modèle is, expressions switch, modèles imbriqués et modèle d’étiquette case d’une instruction switch.

Un autre ensemble de fonctionnalités prend en charge le calcul hautes performances en C# :

  • Les types nint et nuint modélisent les types entiers de taille native sur l’UC cible.
  • Les pointeurs de fonction fournissent des fonctionnalités de type délégué tout en évitant les allocations nécessaires pour créer un objet délégué.
  • Vous pouvez omettre l’instruction localsinit pour enregistrer des instructions.

Performances et interopérabilité

Un autre ensemble d’améliorations prend en charge des scénarios où les générateurs de code ajoutent des fonctionnalités :

  • Les initialiseurs de module sont des méthodes que le runtime appelle lorsqu’un assembly se charge.
  • Les méthodes partielles prennent en charge les nouveaux modificateurs accessibly et les types de retour non void. Dans ce cas, une implémentation doit être fournie.

Caractéristiques d’ajustement et de finalisation

C# 9 ajoute de nombreuses autres petites fonctionnalités qui améliorent la productivité des développeurs, à la fois pour l’écriture et la lecture du code :

  • Expressions new de type cible
  • static fonctions anonymes
  • Expressions conditionnelles de type cible
  • Prise en charge des extensions GetEnumerator() pour les boucles foreach
  • Les expressions lambda peuvent déclarer des paramètres d’abandon
  • Les attributs peuvent être appliqués aux fonctions locales

La version C# 9 poursuit le travail de maintien d’un langage de programmation moderne et universel. Les fonctionnalités continuent de prendre en charge les charges de travail et les types d’applications modernes.

C# version 8.0

Publication : septembre 2019

C# 8.0 est la première version principale de C# qui cible spécifiquement .NET Core. Certaines fonctionnalités s’appuient sur de nouvelles fonctionnalités CLR (common language runtime) et d’autres sur les types de bibliothèque ajoutés uniquement dans .NET Core. C# 8.0 ajoute les fonctionnalités et améliorations suivantes au langage C# :

Les membres de l’interface par défaut nécessitent des améliorations dans le CLR. Ces fonctionnalités ont été ajoutées dans le CLR pour .NET Core 3.0. Les plages et les index, ainsi que les flux asynchrones nécessitent de nouveaux types dans les bibliothèques .NET Core 3.0. Les types de référence pouvant accepter la valeur Nul, tout en étant implémentés dans le compilateur, sont beaucoup plus utiles lorsque les bibliothèques sont annotées pour fournir des informations sémantiques sur l’état null des arguments et des valeurs de retour. Ces annotations sont ajoutées dans les bibliothèques .NET Core.

C# version 7.3

Publication : mai 2018

Il existe deux thèmes principaux pour la version C# 7.3. Un thème fournit des fonctionnalités permettant au code sécurisé d’être aussi performant que le code non sécurisé. Le second thème fournit des améliorations incrémentielles aux fonctionnalités existantes. De nouvelles options de compilateur ont également été ajoutées dans cette version.

Les nouvelles fonctionnalités suivantes prennent en charge le thème de meilleures performances pour le code sécurisé :

  • Vous pouvez accéder à des champs fixes sans épinglage.
  • Vous pouvez réaffecter des variables locales ref.
  • Vous pouvez utiliser des initialiseurs sur les tableaux stackalloc.
  • Vous pouvez utiliser des instructions fixed avec tout type prenant en charge un modèle.
  • Vous pouvez utiliser des contraintes plus génériques.

Les améliorations suivantes ont été apportées aux fonctionnalités existantes :

  • Vous pouvez tester == et != avec des types de tuple.
  • Vous pouvez utiliser des variables d’expression dans d’autres emplacements.
  • Vous pouvez joindre des attributs à un champ de stockage de propriétés implémentées automatiquement.
  • La résolution de la méthode a été améliorée lorsque des arguments diffèrent de in.
  • La résolution de la surcharge comporte maintenant moins de cas ambigus.

Les nouvelles options du compilateur sont les suivantes :

  • -publicsign pour activer la signature d’assemblys Open Source Software (OSS).
  • -pathmap pour fournir un mappage des répertoires sources.

C# version 7.2

Publication : novembre 2017

C# 7.2 a ajouté plusieurs fonctionnalités de langage de petite taille :

  • Initialiseurs sur des tableaux stackalloc.
  • Utilisez des instructions fixed avec n’importe quel type qui prend en charge un modèle.
  • Accéder aux champs fixes sans épinglage.
  • Réaffecter des variables ref locales.
  • Déclarez des types readonly struct pour indiquer qu’un struct est immuable et doit être transmis en tant que paramètre in à ses méthodes membres.
  • Ajoutez le modificateur in aux paramètres pour spécifier qu’un argument est passé par référence, mais qu’il n’est pas modifié par la méthode appelée.
  • Utilisez le modificateur ref readonly sur les retours de méthode, pour indiquer qu’une méthode retourne sa valeur par référence, mais n’autorise pas les écritures dans cet objet.
  • Déclarez des types ref struct, pour indiquer qu’un type de struct accède directement à la mémoire managée et doit toujours être alloué à la pile.
  • Utilisez des contraintes génériques supplémentaires.
  • Arguments nommés non placés en position de fin :
    • Les arguments positionnels peuvent suivre des arguments nommés.
  • Traits de soulignement de début dans les littéraux numériques :
    • Les littéraux numériques peuvent maintenant comporter des traits de soulignement de début avant tout chiffre affiché.
  • Modificateur d’accès private protected :
    • Le modificateur d’accès private protected active l’accès pour les classes dérivées dans le même assembly.
  • Expressions ref conditionnelles :
    • Le résultat d’une expression conditionnelle (?:) peut maintenant être une référence.

C# version 7.1

Publication : août 2017

C# a commencé à sortir versions de point avec C# 7.1. Cette version a ajouté l’élément de configuration de sélection de version de langue, trois nouvelles fonctionnalités de langage et un nouveau comportement du compilateur.

Les nouvelles fonctionnalités de langage de cette version sont :

  • Méthode asyncMain
    • Le point d’entrée pour une application peut avoir le modificateur async.
  • Expressions littérales default
    • Vous pouvez utiliser des expressions littérales default dans les expressions de valeur par défaut quand le type cible peut être inféré.
  • Noms des éléments de tuple inférés
    • Les noms des éléments de tuple peuvent être inférés dans de nombreux cas à partir de l’initialisation du tuple.
  • Critères spéciaux sur les paramètres de type générique
    • Il est possible d’utiliser des expressions de critères spéciaux sur les variables dont le type est un paramètre de type générique.

Enfin, le compilateur a deux options, -refout et -refonly, qui contrôlent la génération d’une assembly de référence.

C# version 7.0

Publication : mars 2017

C# version 7.0 a été publié avec Visual Studio 2017. Cette version présente des points évolutifs et très attrayants dans la veine de C# 6.0. Voici quelques-unes des nouvelles fonctionnalités :

Autres fonctionnalités disponibles :

Toutes ces fonctionnalités offrent de nouvelles capacités aux développeurs ainsi que la possibilité d’écrire du code plus propre. Il s’agit notamment de condenser la déclaration des variables à utiliser avec le mot clé out et en autorisant plusieurs valeurs de retour par le biais d’un tuple. .NET Core cible à présent n’importe quel système d’exploitation et garde les yeux rivés sur le cloud et la portabilité. Ces nouvelles fonctions occupent sans aucun doute les pensées des concepteurs du langage, en plus des fonctionnalités à venir.

C# version 6.0

Publication : juillet 2015

La version 6.0, sortie avec Visual Studio 2015, proposait de nombreuses fonctionnalités plus petites qui rendent la programmation C# plus productive. En voici quelques-unes :

Quelques autres nouvelles fonctions :

  • Initialiseurs d’index
  • Await dans des blocs catch/finally
  • Valeurs par défaut pour les propriétés d’accesseur Get

Si vous examinez ces caractéristiques dans leur ensemble, un modèle intéressant se dégage. Dans cette version, C# a commencé à éliminer le texte réutilisable du langage pour rendre le code plus laconique et plus lisible. Ainsi, pour les amateurs de code propre et simple, cette version du langage était une énorme victoire.

Une autre nouveauté a été proposée avec cette version, même s’il ne s’agit pas d’une fonctionnalité de langage traditionnelle à proprement dit. Le compilateur Roslyn a été publié en tant que service. Le compilateur C# est à présent écrit en C# et vous pouvez l’utiliser dans le cadre de vos efforts de programmation.

C# version 5.0

Publication : août 2012

C# version 5.0, sortie avec Visual Studio 2012, était une version ciblée du langage. Presque tous les efforts déployés pour cette version portaient sur un autre concept révolutionnaire du langage : le modèle async et await pour la programmation asynchrone. Voici la liste des principales fonctionnalités :

L’attribut d’informations de l’appelant vous permet de récupérer facilement des informations sur le contexte d’exécution sans avoir recours à une multitude de code de réflexion réutilisable. Nombre de ses usages ont trait aux diagnostics et aux tâches de journalisation.

Mais async et await sont les véritables vedettes de cette version. Quand ces fonctionnalités sont apparues en 2012, C# a encore modifié la donne en intégrant l’asynchronie en tant que participant de premier ordre dans le langage.

C# version 4.0

Publication : avril 2010

C# version 4.0, publiée avec Visual Studio 2010, avait introduit quelques nouvelles fonctionnalités intéressantes :

Les types d’interopérabilité incorporés ont facilité le déploiement de la création d’assemblys COM Interop pour votre application. La covariance et la contravariance génériques vous donnent plus de contrôle sur l’utilisation des génériques, mais elles sont un peu académiques et probablement plus appréciées des auteurs de frameworks et de bibliothèques. Les paramètres nommés et facultatifs vous permettent d’éliminer les nombreuses surcharges de méthode et s’avèrent plus pratiques. Mais aucune de ces fonctionnalités ne représente un vrai changement de paradigme.

La fonctionnalité majeure était plutôt l’introduction du mot clé dynamic. Le mot clé dynamic introduisit dans C# version 4.0 la possibilité de remplacer le compilateur lors de la saisie au moment de la compilation. En utilisant le mot clé dynamic, vous pouvez créer des constructions semblables aux langages dynamiquement typés comme JavaScript. Vous pouvez créer un dynamic x = "a string", puis y ajouter six, et ainsi laisser le runtime se débrouiller avec ce qui doit se produire par la suite.

La liaison dynamique offre la possibilité de commettre des erreurs, mais également de contrôler davantage le langage.

C# version 3.0

Publication : novembre 2007

C# version 3.0 est apparu fin 2007, en même temps que Visual Studio 2008, même si l’éventail complet des fonctionnalités du langage n’a réellement voir le jour qu’avec le .NET Framework version 3.5. Cette version a insufflé un changement majeur dans l’évolution de C#. Elle a imposé C# en tant que langage de programmation vraiment formidable. Examinons certaines fonctionnalités importantes dans cette version :

Rétrospectivement, nombre de ces fonctionnalités semblent à la fois inéluctables et inséparables. Elles s’assemblent de façon stratégique. L’expression de requête, également appelée LINQ (Language-Integrated Query), fut la fonctionnalité remarquable de cette version de C#.

Un point de vue plus nuancé s’intéresse aux arborescences d’expressions, aux expressions lambda et aux types anonymes sur lesquels se construit LINQ. Mais, dans les deux cas, C# 3.0 présentait un concept révolutionnaire. C# 3.0 jetait les bases qui allaient permettre à C# de devenir un langage fonctionnel/orienté sur objet hybride.

Plus précisément, il devint alors possible d’écrire des requêtes déclaratives de style SQL pour effectuer des opérations sur des collections, entre autres choses. Au lieu d’écrire une boucle for pour calculer la moyenne d’une liste d’entiers, vous pouviez alors simplement utiliser list.Average(). La combinaison des expressions de requête et des méthodes d’extension a permis à de telles listes d’entiers de devenir beaucoup plus intelligentes.

C# version 2.0

Publication : novembre 2005

Examinons certaines fonctionnalités majeures de C# 2.0, sorti en 2005, en même temps que Visual Studio 2005 :

D’autres fonctionnalités de C# 2.0 ajoutaient des capacités aux fonctionnalités existantes :

  • Accessibilité distincte des accesseurs Get/Set
  • Conversions de groupes de méthodes (délégués)
  • Classes statiques
  • Inférence de délégué

Alors que C# avait démarré en tant que langage orienté objet générique, C# version 2.0 a rapidement chamboulé cet état des choses. Avec les génériques, les types et les méthodes peuvent fonctionner sur un type arbitraire tout en assurant quand même la cohérence des types. À titre d’exemple, un List<T> vous permet d’avoir List<string> ou List<int> et d’effectuer des opérations qui maintiennent la cohérence des types sur des chaînes ou entiers alors que vous itérez en leur sein. Il vaut mieux utiliser des génériques que créer un type ListInt qui dérive de ArrayList ou effectuer un cast de Object pour chaque opération.

C# version 2.0 a introduit les itérateurs. En bref, les itérateurs permettent d’examiner tous les éléments dans un List (ou d’autres types énumérables) avec une boucle foreach. Le fait de disposer d’itérateurs comme composants de premier ordre du langage en a considérablement amélioré la lisibilité et la capacité de raisonnement des utilisateurs vis-à-vis du code.

C# version 1.2

Publication : avril 2003

C# version 1.2 était fourni avec Visual Studio .NET 2003. Cette version contenait quelques améliorations mineures du langage. La principale est que, à compter de cette version, le code était généré dans une boucle foreach (appelée Dispose) sur un IEnumerator quand ce IEnumerator implémentait IDisposable.

C# version 1.0

Publication : janvier 2002

Rétrospectivement, le langage C# version 1.0, sortie avec Visual Studio .NET 2002, ressemblait beaucoup à Java. Dans ses objectifs de conception énoncés pour ECMA, il cherchait à être un « langage orienté objet simple, moderne et généraliste ». À l’époque, ressembler à Java signifiait qu’il avait atteint ces objectifs de conception.

Mais si vous repensez à C# 1.0 maintenant, cela peut vous donner le vertige. Il lui manquait des fonctionnalités asynchrones intégrées et certaines des fonctionnalités liées aux génériques qui sont aujourd’hui pour vous une évidence. En fait, il ne proposait pas du tout de génériques. Et LINQ ? Pas encore disponible. Il fallait attendre encore plusieurs années.

C# version 1.0 semblait dénué de fonctionnalités, par rapport à aujourd’hui. Vous vous retrouviez à écrire plus ou moins du code détaillé. Mais il faut bien commencer quelque part. C# version 1.0 était une alternative viable à Java sur la plateforme Windows.

Les principales fonctionnalités du langage C# 1.0 étaient les suivantes :

Articleinitialement publié sur le blog NDepend, avec l’aimable autorisation d’Erik Dietrich et de Patrick Smacchia.