C sharp

Un article de Wikipédia, l'encyclopédie libre.
(Redirigé depuis C Sharp)
Aller à : navigation, rechercher
Page d'aide sur l'homonymie Pour les articles homonymes, voir Sharp et .cs.
C♯
Logo.

Apparu en 2001 (dernière révision en 2010)
Auteur Microsoft
Paradigme structuré, impératif, orienté objet
Typage statique, fort, nominatif
Dialectes 1.0, 1.5 , 2.0 (ECMA), 3.0, 3.5, 4.0
Influencé par Eiffel, Java
Implémentations Microsoft .NET, Mono

Le C♯ (prononcé [siː.ʃɑːp]) est un langage de programmation orienté objet à typage fort, créé par la société Microsoft, et notamment un de ses employés, Anders Hejlsberg, le créateur du langage Delphi.

Il a été créé afin que la plate-forme Microsoft .NET soit dotée d'un langage permettant d'utiliser toutes ses capacités. Il est très proche du Java dont il reprend la syntaxe générale ainsi que les concepts (la syntaxe reste cependant relativement semblable à celle de langages tels que le C++ et le C). Un ajout notable au C♯ est la possibilité de surcharge des opérateurs, inspirée du C++. Toutefois, l'implémentation de la redéfinition est plus proche de celle du Pascal Objet.

Plate-forme d'exécution[modifier | modifier le code]

  • La plate-forme Microsoft .NET (possibilité de mixage avec des modules d'autres langages)
  • Des implémentations libres de ce langage et de sa plate-forme d'exécution sont en cours de finalisation, comme le projet Mono maintenu par Novell, ou dotGNU maintenu par la Free Software Foundation. L'idée fondatrice de ces projets est qu'une application en C♯ puisse s'exécuter sans modification sur une plate-forme propriétaire comme Windows ou libre comme Linux.

Capacités du langage[modifier | modifier le code]

Le C♯ est, d’une certaine manière, le langage de programmation qui reflète le mieux l’architecture Microsoft .NET qui fait fonctionner toutes les applications .NET, et en est par conséquent extrêmement dépendant. Les types natifs correspondent à ceux de .NET, les objets sont automatiquement nettoyés par un ramasse-miettes (garbage collector en anglais), et beaucoup de mécanismes comme les classes, interfaces, délégués, exceptions, ne sont que des moyens explicites d’exploiter les fonctionnalités de la bibliothèque .NET. Pour achever de marquer cette dépendance, le CLR (Common Language Runtime) est obligatoire pour exécuter des applications écrites en C♯, comme l’est la JVM (Java Virtual Machine ou Machine virtuelle Java) pour des applications Java.

Le langage compte un certain nombre de changements par rapport au C/C++ ; On notera particulièrement les points suivants :

  • La manipulation directe de pointeurs 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 code unsafe. 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 des types de valeurs, les types objets, manipulés par le ramasse-miettes, ne pouvant qu’être référencés.
  • Les objets ne peuvent pas être explicitement détruits. Le ramasse-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’interface IDisposable 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 plus typé 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 type void (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 des tableaux n’est pas la même : int[] a = new int[5] remplace int a[5]. Car il s'agit d'une allocation 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[1].
  • Les membres d’une énumération sont rassemblés dans leur propre espace de noms.
  • Le C♯ ne gère pas les templates, mais cette fonctionnalité a été remplacée par les types 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 plusieurs threads).
  • La réflexion totale des types est disponible.
  • Les délégués, qui sont des listes de pointeurs sur fonctions, sont utilisés notamment pour la programmation événementielle.

Capacités introduites avec C♯ 2.0[modifier | modifier le code]

Microsoft mit à disposition du public en octobre 2005, 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.
  • Les types génériques, qui ne sont pas une simple copie des templates 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 de coroutines via le mot-clé yield, équivalent du yield que l’on trouve en Python.
  • Les méthodes anonymes avec des règles de fermeture 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 les liens externes.

Anders Hejlsberg, le père de Delphi, s’est exprimé sur l’implémentation des génériques dans C♯, Java et C++ dans cette interview (en).

La fonctionnalité des types nullables fut fixé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 du CLR 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).

Capacités introduites dans C♯ 3.0[modifier | modifier le code]

Le C♯ 3.0 fut présenté au salon PDC 2005. La version finale est disponible depuis le 19 novembre 2007 au téléchargement sur le site de Microsoft (en) . Les principales nouveautés sont les suivantes :

  • L’ajout des mots-clefs select, from et where pour permettre la formation et l’exécution de requêtes SQL, XML, ou directement sur des collections. Cette fonctionnalité fait partie du programme Language Integrated Query (LINQ) (en).
  • Nouvelle possibilité d’initialisation d'un objet : À la place de Client c = new Client(); c.Nom = "Dupont";, on peut utiliser Client c = new Client{ Nom = "Dupont" };
  • Expressions lambda : ListeTrucs.Where( delegate(Truc x) { return x.Size > 10; } ); devient ListeTrucs.Where( x => x.Size > 10 );
  • Inférence du type des variables locales : string s = "Dupont" peut être remplacé par var s = "Dupont"
  • Introduction des types anonymes : var x = new { Nom = "Dupont" } peut être utilisé à la place de class __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) : permettent la compilation du code sous formes 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ètre this.

Une présentation du C♯ 3.0 et de LINQ peut être trouvée sur la page du centre de développement de .NET Framework.

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…) ne sont cependant pas utilisables avec les versions précédentes de C♯.

Cette version exige Windows XP ou une version supérieure (Vista ou Windows 7). Elle n'est pas disponible pour Windows 2000.

C♯ 4.0[modifier | modifier le code]

La version 4 du langage apporte plusieurs nouveautés :

  • le typage dynamique des variables à l'aide du mot clé dynamic ;
  • les arguments nommés et facultatifs[2] ;
  • le support de la covariance et de la contravariance pour les interfaces et les délégués génériques.

Le framework .NET 4.0 est sorti le 12 avril 2010, accompagné de Visual Studio 2010[3]. Il propose entre autres :

  • la nouvelle bibliothèque parallèle : Task Parallel Library ;
  • une version optimisée de la plate-forme entité d'accès aux bases de données (Entity Framework) via l'utilisation de LINQ ;
  • la version parallèle de LINQ appelée PLINQ.

C♯ 5.0[modifier | modifier le code]

La version 5 du langage permet de programmer plus simplement des programmes asynchrones grâce à l'ajout des mots clés async et await.

Le comportement des closures dans la boucle foreach a été modifié. Il n'est désormais plus nécessaire d'introduire une variable locale dans une boucle foreach pour éviter les problèmes de closure[4].

À noter également les informations relatives à l'appelant[5] permettent de connaître le nom de la méthode qui a appelé une propriété.

Différences entre Java et C♯[modifier | modifier le code]

Bien que le C♯ soit similaire à Java, il existe des différences notables, par exemple :

  • Java n'autorise pas la surcharge des opérateurs ;
  • Java n'a pas de mode unsafe permettant l'arithmétique de pointeurs ;
  • 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 documentation HTML à partir des fichiers sources à l'aide des descriptions Javadoc-syntax, tandis que le C♯ utilise des descriptions basées sur le XML ;
  • C♯ supporte les indexeurs, les méthodes déléguées, et les événements (là où Java se contente du patron de conception Observateur) ;
  • C♯ ne supporte pas les classes anonymes ;
  • C♯ ne supporte que les classes internes statiques ;
  • C♯ supporte les structures en plus des classes (les structures sont des types valeur : on stocke le contenu et non l'adresse) ;
  • C♯ utilise une syntaxe intégrée au langage (DllImport) et portable pour appeler une bibliothèque native, tandis que Java utilise Java Native Interface ;
  • C♯ supporte la généricité, et la machine .NET a été modifiée pour permettre cela (Java la supporte également, mais son implémentation a été réalisée dans le compilateur javac sans changer le bytecode Java). Plus de détails sur l'aspect théorique de cette réalisation peuvent être trouvés dans la référence[6], diapositives 70 à 89.

Standardisation[modifier | modifier le code]

Le C♯ a été normalisé par l'ECMA (ECMA-334) en décembre 2001 et par l'ISO/CEI (ISO/CEI 23270) en 2003.

Les modifications survenues dans la Version 2.0 ont été normalisées par l'ECMA (ECMA-334) en juin 2006 et par l'ISO/CEI (ISO/IEC 23270:2006) en septembre 2006.

Microsoft a ouvert le code source de certaines bibliothèques utilisées par le C♯ en octobre 2007 sous la licence Microsoft Reference License (MS-RL).

Nom du langage[modifier | modifier le code]

C♯ est une note de musique dans le système de notation musical américain (cette note correspond à « Do dièse » dans la notation française). Le symbole ♯ signifie en musique que la note doit être augmentée, l'idée de « C augmenté » rappelle la manière dont le langage C++ a été nommé (++ étant l'opérateur d'incrémentation).

Usuellement, un croisillon (#) est utilisé comme second caractère à la place du dièse (♯) car ce dernier est moins accessible sur le clavier et non reconnu dans certaines polices de caractères.

Le langage[modifier | modifier le code]

Voici un exemple d'un programme Hello world typique, écrit en C♯ :

using System;
 
class HelloWorld
{
    public static void Main()
    {
        Console.WriteLine("Hello World!");
    }
}

Gestion des exceptions[modifier | modifier le code]

C♯ possède les instructions try et catch permettant de gérer les exceptions (comportement non attendu des instructions du programme), similaires dans la syntaxe à celles du C++.
Exemple de code tentant de créer un fichier « document.txt » sur le serveur « Toto » :

try
{
    // Tentative de création du fichier 'document.txt' sur le serveur 'Toto'
    File.Create(@"\\toto\document.txt");
 
}
catch
{
    // Impossible de contacter le server Toto
    MessageBox.Show("L'application n'arrive pas à créer le fichier 'document.txt' sur le serveur 'Toto' !", "Alerte");
}

Notez l'utilisation d'une chaîne de caractères verbatim : le caractère arobase précède le guillemet donc l'anti-slash n'est pas doublé. Ce genre de chaîne de caractères est pratique pour les chemins sous Windows.

Dans cet exemple, la fonction File.Create retourne un flux (FileStream), ou elle peut lancer une exception si une erreur s'est produite (problème de connexion par exemple).

Dans cet exemple, aucune information sur l'exception n'est obtenue : on cherche juste à savoir si le programme ne s'est pas comporté normalement, auquel cas on arrive dans le bloc catch.

À l'instar de C++ qui a un type d'exception de base (class exception dans l'en-tête <exception>) et dont les autres exceptions héritent, toute exception C♯ est héritée (ou une instance) du type System.Exception. Ainsi, si on cherche à savoir ce qui s'est passé, une solution simple reste d'obtenir une référence vers l'exception de la manière suivante :

try
{
    // Tentative de création du fichier 'document.txt' sur le serveur 'Toto'
    File.Create(@"\\toto\document.txt");
 
}
catch(Exception err)
{
    // Impossible de contacter le server Toto
    MessageBox.Show("L'application n'arrive pas à créer le fichier 'document.txt' sur le serveur 'Toto' ! Erreur:" + err.Message, "Alerte");
}

Ainsi, une information complète sera retournée, décrivant la nature de l'exception qui s'est produite.

En fonction des fonctions appelées, le framework .NET fournit la liste des exceptions que l'appel est susceptible de retourner en cas d'erreur. Dans le cas de la fonction 'Create', voici la liste des exceptions possibles :

  • System.UnauthorizedAccessException
  • System.ArgumentException
  • System.ArgumentNullException
  • System.IO.PathTooLongException
  • System.IO.DirectoryNotFoundException
  • System.IO.IOException
  • System.NotSupportedException
try
{
    // Tentative de création du fichier 'document.txt' sur le serveur 'Toto'
    File.Create(@"\\toto\document.txt");
 
}
catch(System.ArgumentException ArgumentErr)
{
    // L'argument n'est pas valable. Le nom de fichier 'document.txt' n'est pas valable
    MessageBox.Show("L'argument n'est pas valable. Le nom de fichier 'document.txt' n'est pas valable ! Erreur:" + ArgumentErr.Message, "Alerte");
}
catch(Exception err)
{
    // Impossible de contacter le server Toto
    MessageBox.Show("L'application n'arrive pas à créer le fichier 'document.txt' sur le serveur 'Toto' ! Erreur:" + err.Message, "Alerte");
}

De la même manière qu'en C++, l'envoi d'une exception se fait avec le mot-clef throw :

public uint Divide(uint num, uint div) //Fonction de division dans N
{
    if(div == 0)
        throw new Exception ("Division par 0 !");
    if(num < div)
        throw new Exception ("num est strictement inférieur à div : le résultat de la division ne sera pas un entier naturel !");
    return num / div;
}
//Code ailleurs :
try
{
    Divide(12, 6); //Retourne 2, aucune exception
    Divide(10, 20); //Exception, cette division ne donne aucun résultat dans N
    Divide(10, 0); //Exception, division par zéro impossible
}
catch (Exception e)
{
    MessageBox.Show("L'erreur suivante a été retournée :\n" + e.Message, "Alerte");
}

L'envoi d'une exception (via throw) ou la levée d'une exception (dans un bloc try/catch) met immédiatement fin au bloc en cours. Ainsi, si div est nul, le code de la fonction Divide s'arrêtera à la ligne 2. De même, dans l'exemple précédent, la troisième fonction Divide ne sera jamais exécutée à cause de la levée d'une exception lors du deuxième appel à Divide. Une exception non attrapée (catchée) - c'est-à-dire que l'application n'a pas encadré le code lançant l'exception par un bloc catch approprié - met fin à l'application immédiatement sous la forme d'une exception de type UnhandledException (exception non gérée en français).

Comme en Java, il est possible d'ajouter un bloc finally pour exécuter une série d'instructions, quoi qu'il se passe (exception lancée ou non). Cela est utile pour libérer des ressources quel que soit ce qui peut se passer entre la prise de ressource et la libération. Exemple typique : lecture de fichiers

FileStream fs = new FileStream(@"C:\Fichier.txt", FileMode.OpenOrCreate, FileAccess.ReadWrite);
// arrivé ici, le fichier est ouvert
try
{
    // ... opérations de lecture / écriture pouvant lancer des exceptions ...
}
finally
{
    // fermer le fichier quoi qu'il se passe :
    fs.Close();
}

Notes et références[modifier | modifier le code]

Liens externes[modifier | modifier le code]

Sur les autres projets Wikimedia :

Quelques Livres[modifier | modifier le code]

  • (fr) C♯ et .NET - Gérard Leblanc - 2002 - Éditions Eyrolles - (ISBN 2-212-11066-9)
  • (fr) C♯ et .NET Version 2 - Gérard Leblanc - 2006 - Éditions Eyrolles - (ISBN 2-212-11778-7)
  • (fr) C♯ Tête la première - Andrew Stellman, Jennifer Greene - 2008 - Éditions Digit Books - (ISBN 978-2-81500-001-7)
  • (fr) Introduction à C♯ - Pierre-Yves Saumont, Antoine Mirecourt - 2001 - Éditions Eyrolles - (ISBN 2-7464-0301-3)
  • (fr) Le guide de survie C♯ - Gilles Tourreau - 2010 - Éditions Pearson Education - (ISBN 978-2-7440-2432-0)
  • (en) C# 2005 Programmer's Reference - Adrian Kingsley-Hughes, Kathie Kingsley-Hughes - 2006 - Édition Wrox - (ISBN 0-470-04641-4)
  • (en) C♯ Essentials, 2nd Edition - Ben Albahari, Peter Drayton, Brad Merrill - 2002 - Édition O'Reilly Media - (ISBN 0-596-00315-3)
  • (en) Professional C♯, 3rd Edition - Simon Robinson, Christian Nagel, Karli Watson, Jay Glynn, Morgan Skinner, Bill Evjen - 2004 - Édition Wrox - (ISBN 0-7645-5759-9)