Langage C# - Les Bases

Dimension: px
Commencer à balayer dès la page:

Download "Langage C# - Les Bases"

Transcription

1 Langage C# - Les Bases 1

2 Table des matières Langage C# - Les Bases 1 Chapitre 1 : Visual Studio.NET 7 1. Introduction 7 2. Fonctionalités de Visual Studio.Net L'éditeur de texte L'éditeur graphique Les fenêtres de support Le débogueur intégré Le système d'aide intégré (MSDN) L'accès à des logiciels externes Conclusion 8 3. Première approche de Visual Studio.net Premier lancement de Visual Studio.Net Création d'un nouveau projet Les différents types de projet C# Différencier les "Solutions" et les "Projets" 14 Notes pour les utilisateurs des versions précédentes de Visual Studio 14 4 Les différentes fenêtres de l'ide Fenêtre "Explorateur de Solutions" La fenêtre "Propriétés" La fenêtre "Affichage de Classes" La fenêtre "Dynamic Help" La Boite à outils ou ToolBox L'explorateur de Serveurs (Server Explorer) Autres fenêtres de l'ide La fenêtre "Task List" La fenêtre "Command Window" La fenêtre "Output" La fenêtre "Autos" La fenêtre "Locals" La fenêtre "Call Stack" ou "pile des appels" La fenêtre "BreakPoints" Fenêtre "Explorateur d'objets" ou "Object Browser" 26 Chapitre 2 : Syntaxe du Langage C# Considérations générales sur la syntaxe Espaces blancs Instructions Structuration par Blocs Indentation du code Commentaires 29 Commentaires simple ligne : // 29 Commentaires multi-lignes : /* */ 29 Commentaires de documentation XML : /// Sensiblité à la Casse Notre premier programme : HelloWorld.cs Les Variables dans C# Concept de variable Représentation en mémoire 34 2

3 Base Notation Binaire 34 Types numériques signés et non-signés 35 Chaînes de caractères (Strings) Déclaration de variables Initialisation de variables Nommage des variables Portée des variables 40 Exemple 40 Différences entre champs et variables locales Constantes 42 4 Les types de données dans C# Types "Valeur" et Types "Référence" 43 Exemple d'affectation à un type valeur 43 Exemple d'affectation à un type Référence 43 Conclusion Types du Common Type System Types Valeur prédéfinis 46 Types d'entiers 46 Types de nombres en virgule flottante 47 Type Decimal 47 Type bool (Booléen) 48 Type Char (caractère) Types Référence prédéfinis 49 Type object 49 Type string opérateurs et expressions Différents types d'opérateurs Opérateurs et raccourcis L'operateur ternaire Opérateurs checked et unchecked Opérateur sizeof Opérateur typeof Préséance des opérateurs Sécurité et Types Conversions de types de données Conversions implicites Conversions explicites Boxing et un-boxing Contrôle du Flux d'exécution Les Instruction Conditionnelles 61 L'instruction if 61 L'instruction switch Les Boucles 65 La boucle for 65 La boucle while 67 La boucle do while 67 La boucle foreach Instruction de saut 69 L'instruction goto 69 L'instruction break 69 L'instruction continue 69 L'instruction return 69 3

4 3. Chapitre 3 : Structure des programmes Les Tableaux en C# Définition Les tableaux à une dimension 70 Initialisation 70 Accès aux éléments du tableau Les tableaux à plusieurs dimensions Les tableaux orthogonaux (jagged arrays) 72 Déclaration 72 Initialisation 72 Parcours des tableaux de tableaux La classe Array et ses méthodes. 74 Propriétés de System.Array Class 74 Méthodes de System.Array Class Les Enumérations Définition et usage Typage sous-jacent des énumérations Méthodes de la classe Enum Les espaces de noms (namespaces) importance des espaces de nom Conventions pour namespaces et répertoires Instruction using Liste des principaux namespaces Classes et Structures Définir des classes et des structures 79 Structures 79 Classes Différence entre une classe et un objet Méthodes dans C# Déclaration de méthodes valeurs de retour Invocation de méthodes La méthode Main et ses différentes syntaxes Passage d'arguments à Main Passage d'arguments par valeur et par référence 83 Mot-clé ref 83 Mot-clé Out Passage de tableaux aux méthodes 83 Mot-clé Params Surcharger des méthodes Membres statiques et Membres d'instance Propriétés Concept d'encapsulation Syntaxe des propriétés Considérations générales 88 Lecture / écriture 88 Accès différents Indexeurs Delegates et Evènements Définition d'un Delegate Exemple d'utilisation d'un delegate simple Delegates Multicast Evènements 91 4

5 Etape 1: Déclarer le delegate. 92 Etape 2: Définir la classe Generateur 92 Etape 3: Définir la classe Client 93 Etape 4: Souscrire à l'évènement et le traiter Chapitre 4 : Déboguage et gestion d erreurs Introduction Déboguage dans Visual Studio.net Déboguage en mode «normal» Afficher des informations de déboguage utiles Déboguage en mode point d arrêt ou pas à pas Entrer en mode Point d arrêt Définir des point d arrêt dans le code Autres moyens d activer le mode arrêt Contrôler le contenu des variables La fenêtre «Variables locales» La fenêtre «Recherche» Différents mode de pas à pas La fenêtre «Command» La fenêtre «Pile des appels» Gestion des Erreurs Les exceptions La structure «try..catch..finally» Lister et configurer des exceptions La Fenêtre Exceptions 105 Chapitre 5 - Concepts Orientés Objet Constructeurs Par défaut Paramétrés Statiques Appeler d'autres constructeurs depuis un constructeur Appeler des constructeurs de la classe de base Destructeurs Syntaxe Notion de Garbage Collector et Finalisation non-déterministe Interface IDisposable et Méthode Dispose Héritage Héritage de classes le mot-clé this le mot-clé base Redéfinition de méthodes Masquage de méthodes Interfaces Implémentation d'interfaces Polymorphisme par les interfaces Héritage d'interfaces Classes Classes abstraites Classes sealed Niveau d'accessibilité des classes et des membres. 119 Annexe 1 Conventions de codage en C# Introduction Conventions de nommage Casse des noms d'éléments (Pascal Casing et Camel Casing) 122 5

6 4. Style des Noms d'éléments Nommage des Namespaces (espaces de noms). 123 Annexe 2 : Caractères d'échappement 124 Annexe 3 Noms et Mots-Clés Liste des mots-clés Visual Basic.NET Liste des mots-clés C# 127 6

7 Chapitre 1 : Visual Studio.NET 1. Introduction Visual Studio.Net est l environnement de développement intégré de Microsoft. Il a été conçu pour rendre aussi faciles que possible l écriture, le déboguage et la compilation de vos programmes. 2. Fonctionalités de Visual Studio.Net En pratique, cela signifie que Visual Studio.Net est une application extrêmement sophistiquée, présentant une interface multi-documents, et dans laquelle vous pourrez effectuer toutes les opérations nécessaires au développement de votre code. Concrètement, l application VS.NET comporte : 2.1 L'éditeur de texte Dans l'éditeur de texte, vous pouvez écrire votre code, quel que soit le langage que vous utilisez. Tous les langages écrits pour supporter la plateforme.net sont pris en compte. Cela inclut C#, Visual Basic.Net, C++.Net, ainsi que tous les autres langages d éditeurs tiers (tel Eiffel.Net, Python.Net, etc..). Cet éditeur profite des derniers développements en matière d'interface utilisateur et supporte la nouvelle version de la technologie IntelliSense qui apporte aux développeurs plus de souplesse et de rapidité dans l'écriture de leur code. 2.2 L'éditeur graphique L'éditeur graphique (ou désigner) permet d'élaborer de manière visuelle une interface utilisateur, que celle-ci soit une interface Windows ou une interface Web. Lorsque vous utilisez ce "designer", Visual Studio.Net traduit automatiquement l'interface graphique les diverses actions réalisées par les développeurs pour créer l'interface graphique en code C# (ou n'importe quel autre langage.net). Les utilisateurs de RAD (comme Visual Basic 6 par exemple) sont déjà habitués à pouvoir créer graphiquement leurs interfaces, mais, auparavant, le code généré était caché aux développeurs, ce qui induisait certaines limitations. Ce n'est plus le cas dans le designer graphique de Visual Studio.Net : toutes les opérations réalisées en mode "graphique" par les développeurs sont désormais traduites en code. 2.3 Les fenêtres de support Cellecs-ci permettent de visualiser et de modifier certains aspects de votre projet. Il existe ainsi des fenêtres pour accéder aux propriétés des objets, des fenêtres permettant l'accès à l'aide, des fenêtres permettant la visualisation des valeurs des variables, etc. Nous étudierons certaines de ces fenêtre plus loin dans ce chapitre. 7

8 2.4 Le débogueur intégré. Il arrive souvent que l'on fasse des erreurs lors d'un processus de développement. Visual Studio.Net comporte donc un débogueur qui vous informe de la nature de ces erreurs, et permet de les identifier plus facilement. Il peut même analyser en temps réel la syntaxe du code que vous êtes en train de taper afin de vous aider à localiser ces erreurs. 2.5 Le système d'aide intégré (MSDN). Le système d'aide de Microsoft, nommé "MSDN" (pour Microsoft Developper Network) est étroitement intégré au fonctionnement de Visual Studio.Net. Ce système d'aide fait partie du package Visual Studio et peut être consulté en tant que tel, mais peut également être consulté au sein même de l'environnement de développement Visual Studio. Visua Studio peut bien sûr appeler la documentation MSDN de façon contextuelle. Par exemple, si vous hésitez sur la signification d'un mot-clé, vous pouvez le sélectionner dans le code, taper sur la touche F1 et Visual Studio.Net affichera la page appropriée dans la documentation MSDN. De nombreuses options sont disponibles permettant à chaque développeur d'appliquer ses préférences personnelles en ce qui concerne le degré d'intégration de MSDN dans Visual Studio.Net. 2.6 L'accès à des logiciels externes. Visual Studio.Net est un outil très ouvert et, par conséquent, permet aux développeurs de personnaliser leur environnement de développement. Parmi les options disponibles, on trouve la possibilité d'exécuter depuis Visual Studio.net des programmes divers paramétrables par les utilisateurs, tout cela sans quitter l'environnement de développement. On peut même naviguer sur le Web au sein de Visual Studio! 2.7 Conclusion Comme vous le constatez, Visual Studio.Net est plus qu'un simple éditeur de texte. Il est l'outil le plus pratique pour créer des applications.net. Cependant, cet outil n'est pas obligatoirement nécessaire pour créer des applications.net : un simple éditeur de texte (comme NotePad) pourrait suffire.. Evidemment, NotePad n'offre pas la même souplesse que Visual Studio.net mais, Microsoft ayant inclus les différents compilateurs dans le Framework SDK (téléchargeable gratuitement sur il est tout à fait possible de ne pas utiliser Visual Studio pour coder des logiciels.net. Par ailleurs, d'autres éditeurs très professionnels sont téléchargeables sur Internet comme par exemple SharpDevelop et WebMatrix (en source libre) ou encore DreamWeaver MX (édité par MacroMedia). SharpDevelop : WebMatrix : DreamWeaverMX: 8

9 3. Première approche de Visual Studio.net Dans cette section nous présenterons les différentes fonctionnalités de L'IDE Visual Studio.net et les différents types de projets que nous pouvons créer en langage C#. Ce chapitre n'a pas pour but de présenter de manière exhaustive toutes les fonctionnalités de l'ide car il faudrait pour cela un livre entier! En effet, cet environnement de développment est si complet qu'il est sans doute plus facile de découvrir ses fonctionnalités avancées au fur et à mesure que nous en aurons l'utilité dans le code. Le très grand nombre de fonctionnalités dans Visual Studio.net tient également au fait que cet IDE permet, outre le développement d'un grand nombre de projets différents, d'utiliser tous les langages implémentant le Framework.net et tout cela dans le même logiciel. De plus, Visual Studio.net peut également servir d'interface pour interagir avec des bases de données ou des services Windows, en présentant une interface graphique adaptée à chacune de ces tâches. Commençons par découvrir ensemble les fonctionnalités "de tous les jours" de Visual Studio.net. 9

10 3.1 Premier lancement de Visual Studio.Net Voici la page d'accueuil de VS.NET telle que vous la verrez lors du premier lancement après l'installation : Cette page est appelée la "page d'accueuil" de Visual Studio.Net. C'est une page HTML qui présente plusieurs onglets : Projects : présente la liste des projets récemment utilisés ou permet la création d'un nouveau projet. Online Resources: cette page vous présente différents liens utiles vers la communauté de développeurs et d'éditeurs travaillant avec la plateforme.net. Par exemple, on peut directement faire des recherches sur MSDN version Web, télécharger des exemples de code, rechercher des services Web effectuant une tâche particulière, etc.. C'est un peu une porte sur le monde de.net. De plus, cette page est configurable et il est possible d'y ajouter ses propres éléments ou services Web. My Profile : Cet onglet vous permet de définir certaines options pour l'environnement de développement Visual Studio, telles que la configuration du clavier (par exemple les anciens développeurs VB peuvent avoir exactement les mêmes raccourcis clavier que dans les version 10

11 précédentes de Visual Studio), l'agencement des fenêtres, le filtre pour l'aide (par exemple pour n'afficher que l'aide concernant un langage particulier et pas les autres), et enfin si vous souhaitez utiliser l'aide MSDN dans une fenêtre intégrée à Visual Studio ou si vous préférez utiliser celle-ci en tant que logiciel tournant indépendamment de Visual Studio Création d'un nouveau projet Vous pouvez créer un nouveau projet soit en cliquant sur le lien approprié sur la page d'accueuil de Visual Studio, soit en allant dans le menu "Fichier\Nouveau\Projet". Dans les deux cas, la boite de dialogue "Nouveau Projet" s'affiche et vous permet de définir les options et le type du nouveau projet à créer. Voici comment se présente cette boite de dialogue : Comme on peut le voir, il existe de nombreux types de projets différents disponibles pour le langage C#. Nous allons expliquer la nature de certains d'entre eux prochainement. On constate que cette boite de dialogue nous permet également de définir le répertoire utilisé pour stocker le projet, ainsi que le nom du projet à créer. La case à cocher "Créer un répertoire pour la solution" introduit le concept de "solution", qui est une notion différente de celle du projet. Nous étudierons les différences entre un projet et une solution dans ce chapitre. 11

12 3.3. Les différents types de projet C# Note : Le but de ce suppor t n'est pas de décrire exhaustivement tous les types de projets pour tous les types de langages. Pour information, en ce qui concerne C++, tous les anciens types de projets sont disponibles (applications MFC, projets ATL, etc..). En ce qui concerne Visual Basic.NET il existe des innovations (avec de nouveaux types de projets comme par exemple "Application Console"). En ce qui concerne C#, nous nous bornerons ici à décrire les types de projets principaux que nous pouvons créer sous C#. Il existe cependant d'autres types de projets C# plus spécialisés sous l'option "Other Projects" ou "Autres projets". C# permet donc la création de nombreux types de projet. Le type d'un projet permet de définir le type d'application qui va résulter de la compilation et du déploiement de ce projet. Application Windows Type de Projet sélectionné Obtention du Code C# et des options de compilation pour générer Un projet contenant un formulaire de base vide répondant aux évènements. Ce type de projet sert à créer des applications avec des interfaces client sous Windows (des EXE) Bibliothèque de Classes Un projet compilable sous la forme de DLL contenant une ou plusieurs classes réutilisable(s) par un autre programme.net Bibliothèque de contrôles Windows Un projet contenant une classe.net possédant une interface utiilisateur et réutilisable par un autre programme.net (comme un contrôle ActiveX dans les versions précédentes de VS. Application Web ASP.NET Un projet contenant une WebForm (page ASP.NET) et permettant de créer une application avec une interface Web. Les pages ASP.NET générant automatiquement le code HTML visualisé dans l'explorateur Internet. Service Web ASP.NET Un projet contenant une classe agissant comme un service Web. Un service Web est une application qui tourne sur un serveur Web et dont un autre programme peut se servir. Bibliothèque de contrôles Web Un projet contenant un contrôle réutilisable et pouvant être appelé depuis une page ASP.NET et qui générera le code HTML nécessaire à son affichage dans un explorateur Internet Type de Projet sélectionné Obtention du Code C# et des options de 12

13 Application Console compilation pour générer Un projet contenant une classe.net et les options de compilation nécessaire à la création d'un projet qui s'exécutera dans une fenêtre de commande DOS. Service Windows Un projet destiné à générer une application de type "service". Un service est une application en général sans interface graphique et tournant en arrière-plan de Windows (NT, XP, 2000 ou plus). Projet Vide Un projet vide. Lors de la création d'un tel projet, vous devrez écrire tout le code en partant de rien. Vous continuerez cependant à bénéficier de toutes les facilités et outils de Visual Studio.Net lors de l'écriture du code. Projet Web Vide Un projet vide mais avec des paramètres de compilation définis pour annoncer au compilateur de générer du code pour des pages ASP.Net Nouveau Projet dans un dossier existant Des fichiers d'un nouveau projet pour un projet vide. Utilisez cette option si vous disposez de fichiers de code source C# (saisis par exemple dans un éditeur de texte) et que vous souhaitez les intégrer dans un projet Visual Studio.Net 13

14 3.4. Différencier les "Solutions" et les "Projets" Nous avons déjà évoqué précédemment dans ce chapitre les termes "solution" et "projet". Ces deux notions sont différentes et il est important de bien comprendre la différence entre les deux.. Un projet est l'ensemble de tous les fichiers de code source et des fichiers de ressources compilables dans un seul assemblage (ou programme). Par exemple, un projet peut être une bibliothèque de classe ou une application avec interface utilisateur Windows, ou encore une application s'exécutant dans une fenêtre DOS (application "Console"). Une Solution est constituée de l'ensemble de tous les projets faisant partie d'un ensemble logiciel particulier destiné à créer une application. Pour mieux comprendre cette différence, rappelons-nous que, lors de la livraison d'une application, cette dernière est vraisemblablement composée du plus d'un assemblage. Par exemple, cette application pourrait contenir une interface utilisateur, quelques contrôles personnalisés et d'autres composants livrés comme des bibliothèques de composants d'application. On pourrait dans certains cas y ajouter encore d'autre éléments, comme par exemple une interface utilisateur spécifique réservée aux administrateurs. Chacune de ces parties pourrait être contenue dans un assemblage séparé, pour des raisons évidentes de réutilisation et de modularité du code. Toutes ces parties, prises séparément, sont chacune considérées comme un projet individuel par Visua Studio. Toutefois, il est plausible que vous dévelopiez tous ces projet en parralèle, les uns interagissant avec les autres. Il serait donc très utile de conserver la possibilité de les éditer comme ensemble unitaire au sein de votre environnement de développement. Visual Studio.Net le permet en considérant que tous les projets font partie d'une seule solution et traite cette solution comme une seule unité qu'il lit et stocke en mémoire et dans laquelle il permet de travailler. C'est pourquoi le comportement par défaut de Visual Studio.net est de créer une solution pour tout nouveau projet que vous créez. Si vous souhaitez ne travailler que sur un seul projet, le fait que celui-ci soit contenu dans une solution sera transparent. Par contre, si par la suite vous voulez intégrer votre projet avec d'autres, il vous suffira d'ajouter les autres projets à la solution pour permettre, par exemple, la compilation de tous les projets contenus dans la solution d'un seul coup. Notes pour les utilisateurs des versions précédentes de Visual Studio Pour les développeurs C++, une solution Visual Studio.NET correspond à un ancien "espace de travail" de projet Visual C++ 6 (stocké dans un fichier.dsw) et un projet Visual Studio.NET correspond à un ancien projet C++ (fichiers.dsp). Pour les développeurs en VB (version 4,5 ou 6), une solution correspond à l'ancienne notion de groupe de projet (fichiers.vbg) et un projet.net rappelle l'ancien projet VB (fichier.vbp) 14

15 4 Les différentes fenêtres de l'ide Dans cette section, nous allons détailler les différentes fenêtres les plus utilisées dans l'ide (Integrated Development Environment). Le but n'est pas un passage en revue exhaustif de toutes les fenêtres disponibles mais de donner un aperçu des fenêtre que l'on utilise couramment Fenêtre "Explorateur de Solutions". Voici une image de la fenêtre "explorateur de solution" : Cette fenêtre permet de visualiser les divers fichiers composant les projets ou solutions actuellement ouverts dans Visual Studio.Net. On voit la relation hiérarchique symbolisée par les différents niveaux dans l'arbre contenant tous les éléments avec, en haut la solution contenant le ou les projets qui la constitue. On voit en dessous le projet ("CsharpN1 Arrays") et en dessous, les divers élements du projet, comme suit : la boite de dialogue "Références" qui, une fois déroulée montrent l'ensemble des assemblages référencés par ce projet Les fichiers constituant le projet (avec deux fichiers de code C# avec une extension.cs, une icône qui deviendra celle de l'application, et un fichier texte associé au projet). 15

16 Lorsque l'on souhaite faire afficher dans la fenêtre concepteur (graphique ou de code) un élément en particulier, il suffit de double-cliquer sur son icône ou son nom dans l'explorateur de projets et le contenu dudit fichier est affiché. NB : Pour renommer un élément, il est toujours conseillé d'utiliser cette fenêtre plutot que de passer par l'explorateur Windows. En effet, si l'on renomme un élément en dehors de Visual Studio, la modification de nom n'est pas répercutée dans Visual Studio, ce qui conduit l'ide à ne plus retrouver le fichier renommé. Dans cet exemple, la solution affiichée ne contient qu'un seul projet mais, dans un processus de développement réel, il n'est pas rare d'avoir plusieurs projets ouverts dans une même solution. 16

17 4.2. La fenêtre "Propriétés" Voici une autre fenêtre que les développeurs ayant utilisé les versions précédentes de Visual Basic reconnaîtront certainement. Nous avons déjà évoqué le fait que les classes pouvaient contenir des propriétés. Nous verrons en détail comment implémenter des propriétés pour une classe donnée dans les chapitres suivants. Voici comment se présente la fenêtre propriétés : Cette fenêtre est faite pour nous permettre d'interagir avec les propriétés d'un objet donné. Une fois un objet sélectionné (si celui-ci posséde des propriétés bien sûr), les noms et les valeurs de chacune des propriétés de cet objet s'affichent dans la fenêtre propriétés. On voit au sommet de cette fenêtre, une liste déroulante contenant la liste de tous les objets dont les propriétés peuvent être affichées par cette fenêtre. Dans cet exemple, on constate que l'objet dont les propriétés sont actuellement affichées s'appelle Form1 et est de type System.Windows.Forms.Form. 17

18 On peut bien sûr interagir avec les valeurs des propriétés via cette fenêtre. Toutes les modifications de propriétés que nous effectuons via cette fenêtre donneront lieu à des modifications dans le code source de l'élement affiché. Il est donc préférable d'utiliser la fenêtre propriétés quand cela est possible car cela nous évite d'écrire du code et c'est beaucoup plus facile! La zone de l'image qui affiche le texte "Misc" est la zone de description qui, une fois une propriété sélectionnée, affiche une description succinte de l'usage de la propriété (pour avoir des informations détaillées, l'aide MSDN est bien sûr plus complète) La fenêtre "Affichage de Classes" Contrairement à la fenêtre propriétés, la fenêtre "affichage de classes" (ou ClassView) trouve son origine dans les environnements de développement C++ et Java. Voici comment se présente cette fenêtre : Comme on peut le constater, la fenêtre "affichage de classes" n'est pas à proprement parler une fenêtre indépendante, mais se présente comme un onglet supplémentaire de l'explorateur de solutions. Elle affiche une vue en arborescence que vous pouvez dérouler pour visualiser exhaustivement les éléments composant votre solution. Dans cet exemple, on voit que la solution ne contient qu'une seule classe nommée ClassTestArrays, située dans le namespace Demos.CsharpN1.Arrays. On voit en dessous du nœud de la classe, la liste des membres de la classes, en l'occurrence, la liste des méthodes que cette classe propose, comme par exemple la méthode Main(String[]), la méthode printvalues(int[]), etc.. Cette vue hiérarchique de tous les éléments de code composant une solution est extrèmement pratique, tant pour la vision globale qu'elle offre, mais également pour atteindre rapidement un élément dans le code. Il 18

19 suffit en effet de double-cliquer sur un élément pour que l'éditeur de code se positionne immédiatement sur celui-ci. On utilisera donc très souvent cette fenêtre pour se déplacer dans le code, ainsi que pour garder une vision globale claire de tous les élémements (classes, méthodes, propriétés, etc..) composant une solution. Icônes du ClassView Vous constaterez que chacun des éléments affichés dans cette fenêtre possède une ou deux icône particulières. Il y a des icônes pour tous les types d'élements que vous pouvez rencontrer dans C#, et également, une icône indiquant l'accessibilité (private, public, protected, etc..) du membre que vous êtes en train de visualiser. Une référence complète des icônes et de leur signification est disponible sur le Web. 19

20 4.4. La fenêtre "Dynamic Help" Voici comment se présente la fenêtre "Dynamic Help" Cette fenêtre permet d'accéder à l'aide MSDN (Microsoft Developer Network) fournie avec Visual Studio. Elle s'appelle "Dynamic Help" car elle son contenu évolue dynamiquement en fonction du contexte dans lequel on se trouve. Par exemple, le contenu de cette fenêtre évolue selon le mot-clé qui se trouve sous le curseur lorsque l'on est dans la fenêtre de code, ou encore selon l'objet actuellement sélectionné dans l'ide, par exemple un bouton ou un autre contrôle situé sur une feuille. NB: cette fenêtre est pratique mais le fait de la garder affichée ralentit le fonctionnement de la technologie d'auto-complétion du code avec IntelliSense. 20

21 4.5. La Boite à outils ou ToolBox La Toolbox est une fenêtre qui vous permet d'ajouter différents types d'éléments dans vos projets. Cette fenêtre n'est pas toujours utile dans tous les types de projets (par exemple, on s'en sert rarement dans un projet de type "Console Application". Elle est principalement utillisée pour aider les développeurs à composer l'interface graphique des applications qui peuvent en posséder une (Application WinForms ou WebForms par exemple), en leur présentant une liste des divers éléments ajoutables dans l'interface sous forme d'icônes.. C'est par exemple via cette fenêtre que l'on pourra ajouter des boutons et autres éléments aux designer graphique pour les Windows Forms.. Voici une représentation de la fenêtre ToolBox telle qu'elle se présente dans une application Windows Forms : On remarque que les différents types de contrôles ou d'éléments sont regroupés thématiquement dans les différents onglets au sommet de la fenêtre ("My User Controls", "Data", "Components", "Windows Forms", etc..). Cette fenêtre a également d'autres fonctionnalités (comme le "Clipboard Ring") qui seront détaillées au fur et à mesure de ce cours. 21

22 4.6. L'explorateur de Serveurs (Server Explorer). La fenêtre "Explorateur de Serveurs" permet de contrôler et d'accéder à certain services tournant sur la machine directement depuis l'environnement de développement Visual Studio. Il est par exemple possible d'administrer/consulter les Logs de la machine, les services tournant sur la machine, les compteurs de performances, les MessageQueue, ainsi que d'accéder à une ou plusieurs instances SQL Server déclarées sur la machine. Le fait de pouvoir interagir directement depuis l'ide avec le serveur de bases de données est une pratique courante et extrêmement pratique. Voici une vue de la fenêtre "Explorateur de Serveurs" : Dans ce graphique, nous pouvons voir les différents types de services disponibles (la liste n'est pas exhaustive et peut varier en fonction des services installés sur la machine) sur une machine nommée "nemesis". On voit que l'on peut explorer la structure d'une base de données (ici, la base de données exemple de Microsoft nommée "Northwind") et consulter ou modifier des données dans les tables, créer ou modifier des procédures stockées, etc.. 22

23 4.7. Autres fenêtres de l'ide L'IDE Visual Studio.net possède un grand nombre de fenêtres dédiées à différentes tâches et il n'est pas possible de toutes les énumérer ici. Nous en étudierons certaines fréquemment lors de nos développement et d'autres seront moins fréquemment utilisées, tout cela dépend du type de développement que vous effectuerez. Parmi les fenêtres très couramment utilisées on peut citer : La fenêtre "Task List" Cette fenêtre affiche le résultat de la compilation, recense la liste des erreurs et avertissements, et qui vous permet également d'ajouter des tâches de développement que vous devez vous rappeler de faire (un peu comme le gestionnaire de tâches d'outlook). Voici par exemple un apercu de la fenêtre "Task List" nous présentant la liste des tâches à effectuer (en général, ce sont des erreurs ou des avertissements à corriger): Ici, on voit clairement la nature de chaque tâche et dans quel fichier et à quelle numéro de ligne effectuer celle-ci La fenêtre "Command Window" Celle-ci possède deux modes pour deux utilisations distinctes. En mode Command, elle permet d'appeler des commandes standards de l'ide de manière rapide (comme par exemple ajouter une classe ou fermer un projet), et en mode "Immed" (pour "Immédiat"), elle permet d'afficher la valeur de certaines variables ou expressions lors d'une exécution en pas-à-pas 23

24 4.7.3 La fenêtre "Output" Cette fenêtre affiche des indications sur les évènements qui se sont produits durant l'exécution de ou des assembly qui sont chargés. Il existe d'autres fenêtres (dont nous utiliserons la plupart), dont celles dédiées au déboguage des applications et que l'on n'utilise qu'en mode pas-à-pas : La fenêtre "Autos" Cette fenêtre affiche la valeur des variables contenues dans la ligne en cours d'exécution et dans la ligne qui suit. A noter qu'en Visual Basic.net, cette fenêtre affiche les valeurs pour la ligne en cours et pour les trois lignes au dessus et en dessous de la ligne en cours). On peut également via cette fenêtre modifier directement la valeur des variables affichées lors du pas-à-pas La fenêtre "Locals" Cette fenêtre permet d'afficher les valeurs de toutes les variables et éléments qui sont dans la portée en cours. On peut également modifier les valeurs de ces éléments directement via cette fenêtre durant une exécution en pas-à-pas. 24

25 4.7.6 La fenêtre "Call Stack" ou "pile des appels" Cette fenêtre affiche la pile des appels de procédure et nous permet de naviguer dans le code dans à travers les différents niveaux d'appels de procédures La fenêtre "BreakPoints" Cette fneêtre affiche la liste des points d'arrêts définis dans le code avec leurs numéros de ligne, les classes et les fonctions dans lesquels ils sont définis, ainsi que les différentes conditions qui régissent leur activation, comme par exemple la condition de déclenchement et le nombre de passages obligatoires avant le déclenchement de chacun d'entre eux. 25

26 5. Fenêtre "Explorateur d'objets" ou "Object Browser" La fenêtre "Explorateur d'objets" vous permet d'examiner et de découvrir les éléments (espaces de noms, classes, structures, interfaces, énumérations, etc..) et leurs membres (méthodes, propriétés, évènements, etc..) de tous les composants existant dans ou étant référencés par l'assemblage en cours. C'est une fenêtre pratique pour avoir une vue d'ensemble des élements d'un assemblage ou espace de nommage particulier. La possibilite de trier les éléments par type, par nom ou encore par accès (public, private, etc..) permet de naviguer facilement et de trouver rapidement l'information que l'on souhaite. Une fonction de recherche est également fournie qui est très pratique pour accéder rapidement à un membre donné. Voici une vue possible de l'explorateur d'objets : Note : Il existe cependant un outil d'un éditeur tiers qui remplit toutes les fonctions de l'explorateur de projets avec une interface plus conviviale et qui présente des fonctionnalités plus complètes. Ce logiciel se nomme.net Reflector et est utilisé largement dans la communauté.net. Il est téléchargeable ici : En plus d'offrir de meilleures fonctionnalités (et d'être plus convivial) que l'explorateur d'objet natif de Visual Studio,.net Reflector (appelé ainsi à cause de la technologie de réflexion qui permet à du code d'inspecter les méta-attributs d'un élément), propose un desassembleur en code IL, ainsi qu'un décompilateur en Visual Basic ou en C#! Cet outil gratuit est l'un des outils indispensables de tout développeur C# et une visite régulière sur le site de son auteur Lutz Roeder vous permettra de profiter des lumières de l'un des pionniers du développement.net. 26

27 Chapitre 2 : Syntaxe du Langage C# 1. Considérations générales sur la syntaxe La structure et le fonctionnement du code C# sont en grande partie similaires à ceux de C++ et de Java. Au premier abord, la syntaxe de C# peut paraître confuse et moins intuitive que celles de certains langages utilisant plus de mots anglais intelligibles (comme par exemple Visual Basic 6 ou VB.NET). Cependant, après une immersion dans le langage C#, vous constaterez que sa syntaxe stricte et très concise permet l'écriture d'un code extrêmement clair et facilement maintenable. 1.1 Espaces blancs A la différence des compilateurs des autres langages, le compilateur C# ne tient pas compte des espaces supplémentaires figurant dans le code, que ceux-ci soient des caractères Espace, Tabulation ou Retour chariot (caractères communément appelés espaces blancs). Ceci signifie que vous avez une totale liberté pour formater votre code comme vous le souhaitez, bien que certaines règles communément admises augmentent la lisibilité du code. Certaines conventions de codage sont présentées en annexe de ce support et vous présentent les options de formatage du code les plus courantes. 1.2 Instructions Le code C# est composé d'instructions. Chacune de ces instructions doit se terminer par un caractère "point-virgule", indiquant la fin de l'instruction. Une même ligne peut donc théoriquement comporter plusieurs instructions, cependant, il est d'usage de commencer une nouvelle ligne après chaque point-virgule de fin d'instruction Par contre, il est tout à fait courant que des instructions très longues et qui dépasseraient la largeur d'une page écran soit réparties sur plusieurs lignes. Par convention, on essaye de ne pas écrire de lignes de code dont la largeur est supérieure à celle d'un écran imaginaire de 80 colonnes, ceci parceque pratiquement tous les écrans peuvent afficher cette résolution. 1.3 Structuration par Blocs Le langage C# est un langage structuré par blocs, ce qui signifie que toutes les instructions sont encadrées dans des blocs délimités par une paire d'accolades. Ces blocs peuvent contenir une ou plusieurs instructions, ou encore être vides. Notez qu'une accolade n'est en elle-même pas une instruction et ne doit par conséquent pas être suivie d'un point-virgule. Un bloc de code C# peut dont se présenter ainsi : <ligne de code 1, expression 1>; <ligne de code 2, expression 2> <ligne de code 3, expression 3>; 27

28 Dans cet exemple les sections <ligne de code X, expression Y> ne sont pas du code exécutable C# mais du texte générique représentant n'importe quelle instruction. Ici, les deuxième et troisième lignes font partie de la même instruction, car la deuxième ligne ne se termine pas par un point-virgule. 1.4 Indentation du code Dans l'exemple précédent, nous avons utilisé l'indentation pour rendre le code C# plus lisible et rendre plus facile l'identification du début et de la fin des blocs. Il s'agit d'un pratique courant en programmation et cela fait partie des bonnes conventions de formattage du code. D'ailleurs, Visual Studio.net indente par défaut le code mais vous devrez le faire vous-même si vous n'utilisez qu'un éditeur de texte standard pour l'écriture du code. En régle générale, chaque bloc de code possède son propre niveau d'indentation. Les blocs de code peuvent être imbriqués les uns dans les autres et, dans ce cas, on utilise l'indentation de manière à identifier clairement de à quel bloc de code les instructions appartiennent : <ligne de code 1>; <ligne de code 2>; <ligne de code 3>; <ligne de code 4>; 28

29 1.5 Commentaires Les commentaires sont d'autres éléments courant dans le code C#, comme dans presque tous les langages de programmation. Il est d'usage d'insérer des commentaires décrivant l'action de blocs de code, de façon à faciliter la relecture du code. Les commentaires n'augmentent pas la taille des exécutables produits et ne sont pas pris en compte par le compilateur (sauf éventuellement pour les commentaires servant à générer la documentation XML). Il existe trois syntaxes de commentaires en C# : Commentaires simple ligne : // Les commentaires simple ligne peuvent être placés sur n'importe quelle ligne après deux caractères "slash" ("//"). Le double-slash indique le début du commentaire et la fin de la ligne indique la fin du commentaire. // Ceci est un commentaire Commentaires multi-lignes : /* */ Dans cette notation, les commentaires commencent par "/*" et se terminent par "*/". Cette notation est généralement utilisée pour écrire plusieurs lignes de commentaire sans avoir à inscrire un double-slash au début de chaque ligne, ou encore pour commenter plusieurs lignes de code d'un seul coup. Le commentaire ci-dessous est valide : /* Ceci est la première ligne du commentaire Ceci est la deuxième ligne du commentaire */... Code... Le commentaire suivant génère une erreur /* les commentaires sont souvent terminés avec la syntaxe "*/" */ En effet, les caractères figurant après "/*" sont considérés comme étant hors du commentaire, ce qui entraine une erreur de compilation. Commentaires de documentation XML : /// Il existe en C# un troisième type de commentaires qui servent à générer des fichiers d'aide. Ces commentaires ont une syntaxe spéciale basée sur XML et commencent par trois slash. Les commentaires XML possèdent différentes balises selon le type d'élement qu'ils documentent. Lors de la compilation, les commentaires XML sont extrait du code et insérés dans un fichier XML. On peut ensuite se servir de ce fichier pour générer de la documentation dans divers formats, il suffit pour cela de transformer le code XML en un format plus lisible, par exemple en HTML Visual Studio.net possèdent un outil d'auto-génération de pages web de documentation permettant la génération d'un mini-site en HTML exposant la documentation de la solution en cours sous une forme conviviale. 29

30 Voici un exemple de commentaire de documentation XML /// <summary> /// Fonction permettant l'addition de deux entiers /// </summary> /// <param name="nombre1">un entier</param> /// <param name="nombre2">un autre entier</param> /// <returns>le résultat de l'addition des deux nombres.</returns> static long addition (int nombre1, int nombre2) return (nombre1 + nombre2); Dès que l'on tape un triple slash ("///"), Visual Studio analyse le type de membre au dessus duquel le curseur se trouve et génère les balises XML nécessaires à sa description dans l'aide. Il ne nous reste plus qu'à documenter le membre en question et l'aide sera automatiquement générée sur demande par Visual Studio ou un autre outil de génération de documentation XML tel l'utilitaire Ndoc (téléchargeable sur : Une référence complète des balises de documentation XML se trouve dans la documentation MSDN avec le titre : "Recommended Tags for Documentation Comments" et à l'adresse : ms-help: //MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/csref/html/vclrftagsfordocumentationcom ments.htm 30

31 1.5 Sensiblité à la Casse Il est extrêment important de noter que le langage C# est sensible à la casse, c'est-à-dire qu'il différencie les majuscules des minuscules. Cela peut causer des erreurs difficiles à trouver pour les débutants. Par exemple, si l'on considère le code suivant :... code... int aa;... AA = 0; // attention! ici AA est en majuscules Ce code provoquera une erreur du compilateur car la variable "aa" n'est pas la même que la variable "AA" qui n'a pas été déclarée. Le compilateur indique donc que la variable "AA" n'existe pas. Ce peut paraître une contrainte mais c'est en fait très pratique pour peu que l'on se fixe des règles de codage strictes. Un certain nombre de ces règles peuvent être consultées dans l'annexe de ce support nommée "Conventions de codage". NOTE : Un excellent document sur les conventions de codage et les bonnes pratiques de programmation avec C# et.net est disponible sur le site de Juwal Lowy sur le site net à l'adresse suivante : CSharp Coding Standard.zip 31

32 2. Notre premier programme : HelloWorld.cs Commençons à rentrer dans la pratique en examinant l'exemple de code suivant stocké dans le fichier "helloworld.cs" using System; namespace CSharp.Introduction class Class1 /// <summary> /// Point d'entrée de l'application /// </summary> [STAThread] static void Main(string[] args) string message; message = "Hello World!"; Console.WriteLine("Hello World!"); Tout d'abord voici ce que fait cette application : elle affiche le texte "Hello World" dans la fenêtre de commande DOS. On peut constater que tous les éléments syntaxiques (points-virgule, accolades, commentaires, code indenté) abordés dans les points précédents figurent bien dans ce code. En fait, la section de code suivante est la plus importante pour notre exemple : [STAThread] static void Main(string[] args) string message; message = "Hello World!"; Console.WriteLine(message); Il s'agit du code exécuté lors du lancement de l'application console. Plus exactement, le code exécuté est tout ce qui se trouve entre les accolades. Nous ne nous préoccuperons pas des autres lignes de code dans cet exemple (comme par exemple la manière dont l'application atteint l'instruction Console.WriteLine(message); car l'objectif de ce chapitre est d'étudier la syntaxe C# de base. Les premiers éléments que nous allons détailler sont les variables. 32

33 3. Les Variables dans C# 3.1 Concept de variable La mémoire vive (ou RAM) d un ordinateur est donc constituée d un grand nombre de cases (bits), chacune d entre elles pouvant prendre soit la valeur 0 soit la valeur 1. Chacune de ces cases possède une «adresse», ce qui permet d identifier la case de manière unique. Or ce ne serait pas très pratique d avoir à gérer (et à mémoriser) les adresses de toutes les données que nous désirons stocker dans la mémoire. On dispose donc de ce que l on appelle des variables. Une variable n est donc rien de plus qu un zone de la mémoire, à laquelle on va référer non par son adresse mais par un nom, qui sera le nom de la variable. Lorsque l on souhaitera interagir avec cette zone particulière de la mémoire (soit dit, lire son contenu ou écrire dans son contenu), on référera à la zone en question par le nom de la variable. Definition : laquelle Une variable est une zone dans la mémoire auquelle on a affecté un nom. Une fois une variable déclarée, on peut interagir avec la zone mémoire vers "pointe" la variable pour y stocker ou y lire des données. Les variables possèdent : Un nom Un Type de données Une portée Une valeur Chaque variable possède un type bien particulier qui indique au compilateur le volume nécessaire que celuici doit réserver dans la mémoire pour la variable. Le volume de mémoire occupé par une variable dépendra donc du type de données que l on aura affecté à la variable. La portée d une variable définit en gros son étendue et l'état de sa visibilité par rapport à d'autres éléments. Par exemple, si une variable vara est définie dans une procédure ProcA() est-ce que la procédure ProcB() pourra voir et utiliser cette variable? Cela dépend de ce que l on appelle la portée de la variable Note : en fait ceci est une simplification du concept de portée car la portée d'une variable peut également dépendre de sa position dans la classes, ainsi que de plusieurs autres paramètres que nous détaillerons lorsque nous aborderons la création de classes. Pour l'instant, considérons seulement que la portée d'une variable définit sa visibilité par rapport à d'autres éléments de code. Regardons maintenant comment la manière dont les valeurs des variables sont stockées en mémoire. 33

34 3.2 Représentation en mémoire Les ordinateurs utilisent pour un système de notation en bits pour stocker des valeurs temporairement dans la mémoire vive ou RAM de l ordinateur. Ceci veut dire que, quelle que soit la valeur et le type de données que l on souhaite stocker dans la mémoire vive, celle-ci pourra toujours être décrite sous la forme d une suite de bits. Examinons tout d abord comment fonctionne la notation binaire (sous forme de bits) : Prenons l exemple du chiffre 27. En notation binaire, ce chiffre vaut 11011, chaque nombre représentant une puissance de 2. Le diagramme suivant nous montre comment le chiffre 27 est représenté en base 10 et en notation binaire : Base 10 En base 10, chaque chiffre (2 et 7) représente une puissance de 10. Pour trouver quel chiffre est représenté par la «suite de nombre en base 10», on multiplie chaque nombre par la puissance de 10 correspondant à sa position et l on additionne tous les chiffres ainsi obtenus : (7 * 10 0 ) + (2 * 10 1 ) = Notation Binaire En notation binaire (ou base 2), chaque chiffre représente une puissance de 2. Pour calculer quel chiffre est représenté par la «suite de nombre en base 2»», on multiplie chaque nombre par la puissance de 2 correspondant à sa position et l on addition tous les chiffres ainsi obtenus : (1 * 2 4 ) + (1 * 2 3 ) + (1 * 2 1 ) + (1 * 2 0 ) = On constate d après le diagramme suivant que le plus grand nombre que nous pouvons stocker sur 8 bits est 255 (ou en notation binaire) En effet : (1*2 0 )+(1*2 1 )+(1*2 2 )+(1*2 3 )+(1*2 4 )+(1*2 5 )+(1*2 6 )+(1*2 7 ) = 255 Mais nous n avons évoqué ici que le cas des nombres entiers positifs. Comment serait par exemple stocké le chiffre négatif 27? 34

35 Types numériques signés et non-signés Ce problème est résolu en réservant un bit pour stocker le signe, avec une valeur de 1 pour le signe Plus et une valeur de 0 pour le signe Moins, comme démontré dans le tableau ci-dessous : Signe ou On remarque que l étendue des chiffres que nous pouvons stocker sur 8 bits va maintenant de 128 à Il faut donc distinguer, pour les valeurs numériques les types de données «signés» et les types de données «non-signés». Les types signés réservent un de leurs bits pour stocker le signe, alors que les types non-signés n ont pas de bits réservés pour le signe. Par exemple voici les bornes minimales et maximales pour une variable numérique sur 8 bits (appelé également octet ou Byte) signée et non signée : Type de variable Borne Min Borne Max Signée Non-Signée Un procédé similaire est utilisé pour stocker des nombres décimaux (i.e. un bit est réservé pour stocker l emplacement de la virgule) Chaînes de caractères (Strings) Il va de soi que l on peut vouloir stocker dans la mémoire des informations non-numériques, par exemple des chaînes de caractères. Regardons maintenant comment sont représentées en mémoires ces chaînes de caractères : Supposons donc que nous voulions stocker dans la mémoire la chaîne de caractères «abcde» Les ordinateurs ne comprennent que les valeurs numériques. Il n est donc pas possible de stocker directement les lettres dans la mémoire. Au lieu de cela, nous allons stocker dans la mémoire l équivalent numérique de chacune des lettres de la chaîne de caractères. On utilise pour cela la classification standard ASCII (American Standard Code for Information Interchange) ou encore la classification UNICODE. Dans le standard ASCII, chaque lettre occuppe un octet et dans le standard UNICODE, chaque lettre occuppe deux octets (la classification UNICODE a été définie pour permettre de stocker tous les caractères existant dans toutes les langues, ce qui explique pourquoi stocker un caractère UNICODE prend deux octets alors que l'on en prend q'un en ASCII). 35

36 Le problème des chaînes de caractères est donc résolu de cette manière. Pour chaque caractère d une chaîne, on va stocker son équivalent numérique dans un octet ou deux octets de données. 36

37 3.3 Déclaration de variables Pour déclarer une variable en C#, il suffit de spécifier son nom et son type comme suit : <type> <name>; par exemple : int monentier; // déclare un entier sur 32 bits non-signé Toute variable doit être initialisée avant son utilisation. Une fois la variable monentier déclarée, nous pouvons affecter une valeur à la variable en utilisant l'opérateur d'affectation = : monentier = 10; Nous pouvons également déclarer la variable et initialiser sa valeur en même temps avec la syntaxe suivante : int monentier = 10; Si nous déclarons et initalisons plusieurs variables dans une seule instruction, les variables seront toutes de même type : int monentier1 = 10, monentier2 = 20; Pour déclarer des variables de types différents, nous devons utiliser des instructions séparées; n'affectez pas des types de données différents dans une ligne de déclaration de plusieurs variables int x = 10; // déclaration correcte int y = 20; // déclaration correcte bool z = true; // déclaration correcte int x = 10, y = 20; // déclaration correcte de deux int int x = 10, z = true // ATTENTION : incorrect!! 37

38 3.4 Initialisation de variables L'initialisation de variables montre l'accent mis sur la sécurité dans C#. En bref, le compilateur C# exige que toute variable soit initialisée avec une valeur de départ avant que le programmeur puisse s'y référer dans une opération. Le compilateur C#, qui est très strict, traite les violations de ce principe comme des erreurs. Ceci empêche de récupérer par inadvertance dans la mémoire des valeurs résiduelles provenant d'autres programmes. La langage C# utilise deux méthodes pour s'assurer que les variables sont initialisées avant leur utilisation : les variables correspondant à des champs dans une classe ou dans une structure sont remises à zéro par défaut au moment de leur création si elle ne sont pas initialisées les variables qui sont locales pour une méthode doivent être explicitement initialisées dans le code préalablement à toute instruction utilisant leur valeur. Dans ce cas, il n'est pas nécessaire que l'initialisation ait lieu au moment où la variable est déclarée. Toutefois, le compilateur vérifiera tous les passages possibles par la méthode et signalera une erreur s'il détecte une possibilité quelconque d'utilisation d'une variable locale avant son initialisation. NB: oublier d'initialiser une variable avant de l'employer dans une expression est une erreur très commune chez les débutants en C#. Un bon moyen mnemotechnique pour se souvenir qu'il faut initialiser les variables avant usage est de penser que si on ne le fait pas, la variable peut "pointer" n'importe où dans la mémoire (par exemple sur une zone déjà occupée par une autre variable dans l'application en cours ou même dans une autre application). Quoi qu'il en soit, le compilateur C# nous signale ces erreurs lors de la compilation et il est donc facile de les corriger. 38

39 3.5 Nommage des variables Les noms de variables sont soumis à quelques règles et ne peuvent comporter n'importe quelle séquence de caractères. En pratique ce n'est pas très contraignant car le système de nommage adopté par C# laisse une grande liberté aux programmeurs. Les règles de bases pour le nommage des variables C# sont les suivantes : - le premier caractère d'un nom de variable doit être une lettre, un arobase ("_") ou un ampersand ("@"). - les caractères suivants ne peuvent être que des lettres, des arobases ou des chiffres. - aucun espace n'est autorisé. - Il convient de ne pas nommer une variable (ou un quelconque élément) du même nom qu'un mot-clé du langage C#. - En raison des possibilité d'interopérabilité entre langages, si on veut qu'un assemblage soit dit "CLS Compliant" (soit-dit se 'pliant aux règles du CLS'), il faut également éviter d'utiliser les mots-clés d'autres langages comme VB.NET. NB : pour une référence complète de tous les mot-clés du langage C# et de tous les mots-clés de VB.NET, consultez l'annexe "Mots-clés du langage". Par ailleurs et comme énoncé plus haut dans ce chapitre, des règles et conventions de nommage en fonction de divers critères (but, portée, accessibilité) sont décrits dans l'annexe de ce support nommée "Conventions de codage", ainsi que dans le document "C# Coding Standards", téléchargeable à l'adresse suivante : CSharp Coding Standard.zip 39

40 3.6 Portée des variables Définition : La portée d'une variable est la zone de code à partir de laquelle la variable est accessible. En général, la portée d'une variable est définie selon les règles suivantes : - Un champ (également connu sous le nom de variable membre) d'une classe est visible aussi longtemps que la classe qui le contient est dans la portée (il en est de même en C++ et en Java) - Une variable locale est visible jusquà ce qu'un accolade fermante indique la fin du bloc d'instructions ou de la méthode dans laquelle elle a été déclarée. - Une variable locale déclarée dans une boucle for, while ou similaire est visible dans le corps de cette boucle. Les programmeurs C++ auront remarqué que ce comportement est identique à celui de la norme ANSI pour C++. Exemple using System; namespace CSharp.Introduction public class TestPortee public static void Main() for (int i = 0; i < 10; i++) Console.WriteLine(i); // la variable i sort de portée ici // on peut déclarer une autre variable i car il n'existe pas // d'autre variable de même nom dans la portée for (int i = 9; i >= 0; i--) Console.WriteLine(i); // la variable i sort de portée ici Ce code affiche les nombres de 0 à 9, puis les nombres de 9 à 0 avec deux boucles for. On note que nous avons déclaré la variable i deux fois au sein de la même méthode. Ceci est possible car la variable i est déclarée dans deux boucles séparées, de sorte que chaque variable i est une variable locale dans sa propre boucle. 40

41 Cet autre exemple est incorrect et nous obtiendrons une erreur à la compilation : using System; namespace CSharp.Introduction public class TestPortee public static void Main() int j = 20; for (int i = 0; i < 10; i++) int j = 30; // INCORRECT : croisement de portées Différences entre champs et variables locales Dans certaines circonstances, nous pouvons distinguer deux variables de même nom et de portées indentiques. En fait, C# fait une différence fondamentale (que nous étudierons en détail plus loin dans ce support) entre les variables déclarées au niveau du type (champs) et les variables déclarées dans des méthodes (variables locales). Si nous examinons le code suivant : public class TestPortee2 static int j = 20; // ici j est un champ statique de la classe public static void Main() for (int i = 0; i < 10; i++) int j = 30; // ici j est une variable locale à Main() Console.WriteLine(j); Ce code est compilé sans problème ( et imprime 10 fois "30") malgré la présence de deux variables j dans la portée de la méthode Main() : la variable j définie comme un champ statique de la classe ne sort de portée que lorsque la classe est détruite, et la variable j définie dans le corps de la boucle dans la fonction Main(). Comment ferions nous pour nous référer depuis l'intérieur de la boucle à la variable de niveau classe? Ici nous souhaitons donc accéder à un champ statique de la classe depuis une méthode statique. Il faut utiliser la syntaxe NomClasse.NomChamp. 41

42 Si nous modifions donc le code comme suit, le résultat de l'éxécution de ce programme sera l'impression de 10 fois la valeur 20. public class TestPortee2 static int j = 20; // ici j est un champ statique de la classe public static void Main() for (int i = 0; i < 10; i++) int j = 30; // ici j est une variable locale à Main() Console.WriteLine(TestPortee2.j); 3.7 Constantes Une constante est une variable dont la valeur ne peut pas être modifiée durant toute sa durée de vie. Le fait d'ajouter à une déclaration de variable le préfixe const (lorsqu'elle est déclarée et initialisée) transforme cette variable en constante. Par exemple const int a = 100; Les constantes possèdent les caractéristiques suivantes : - Elles doivent être initialisées lorsqu'elles sont déclarées. - La valeur d'une constante doit être calculable lors de la compilation - Les constantes sont implicitement statiques, cependant il n'est pas permis d'utiliser le modificateur static pour déclarer une constante. L'utilisation de constantes dans le code rend celui-ci plus modulaire et plus facile à maintenir. Par exemple, plutôt que d'utiliser des "nombres magiques" à plusieurs emplacements différents du code, une constante nous permet d'avoir un endroit centralisé pour définir la valeur. Par la suite, toute modification de la valeur de la constante se répercutera dans toutes les méthodes faisant appel à cette constante. Ceci est bien sûr un gage de souplesse et les programmeurs sont encouragés à utiliser des constantes pour définir toutes les valeurs constantes dans le code. Note: Plus loin dans ce support, nous aborderons la notion d'énumérations (qui sont des constantes fortement typées). Il est préférable d'utiliser des énumérations pour définir des jeux de valeurs constantes se référant à un même sujet. Ceci sera expliqué en détail dans la section consacrée aux énumérations. Pour l'instant, utilisez des constantes quand nécessaire 42

43 4 Les types de données dans C# 4.1 Types "Valeur" et Types "Référence" Le langage C# fait la distinction entre deux catégories de types de données : - Les types "Valeur" - Les types "Référence" La syntaxe des types valeurs et référence sera étudiée en détail dans les prochaines sections et pendant toute la durée du cours. D'un point de vue conceptuel, la différence entre ces deux familles de types de données est que les types valeurs stockent directement leur valeurs, alors que les types référence stockent une référence vers la valeur (c'est-à-dire qu'ils ne contiennent pas la valeur mais en fait l'adresse à laquelle est stockée cette valeur en mémoire). Les types sont stockés en mémoire à différents emplacements : - Les types valeur sont stockés dans une zone appelée "pile" - Les types référence sont stockés dans une zone appelée "tas managé" Il est très important de savoir distinguer les différences fonctionnelles entre un type valeur et un type référence, en raison principalement des différences de comportement de ces deux familles de types quand on leur affecte des valeurs. Exemple d'affectation à un type valeur Prenons pour l'exemple deux variables de type int. Le type int est un type valeur, ce qui implique comme précedemment indiqué que les variables de ce type stockent directement leur valeurs en mémoire. int i = 10; int j = i ; Le code ci-dessus utilisera donc deux emplacements distincts en mémoire : un pour i et un pour j. Si plus loin dans le code nous exécutons la ligne suivante : j = 50; Cela n'affectera que la valeur de j et non la valeur de i. La variable i vaudra toujours 10 et la variable j vaudra 50. Exemple d'affectation à un type Référence Imaginons pour cet exemple que nous disposons d'une classe TestClass. Cette classe posséderait un champ de type int nommé value. Regardons maintenant la différence des effets exercés par l'affectation en examinant le code suivant : 43

44 TestClass x; TestClass y; x = new TestClass(); // Création d'une instance de TestClass x.value = 10; // affectation de la valeur 30 au membre value. y = x; // ici y POINTE SUR LE MEME OBJET QUE X! Console.WriteLine(y.value); // affichage de la valeur de y.value 10 y.value = 20; Console.WriteLine(x.value); // affichage de la valeur de x.value 20 Il existe dans ce code un seul objet TestClass : x et y pointent toutes deux vers l'emplacement mémoire contenant cet objet (on peut dire qu'ils font tout deux "référence" au même emplacement mémoire). Comme x et y sont des variables de type référence, la déclaration de chacune de ces variables réserve simplement une référence; elle n'instancie pas un objet du type donné. C'est la raison pour laquelle, lorsque l'on modifie y.value, on modifie également x.value. Note : cela équivaut à déclarer un pointeur en C++ ou une référence d'objet en VB : en aucun cas un deuxième objet n'est créé. Puisque x et y se réfèrent au même objet, toutes les modifications effectuées sur x affecteront y (et vice-versa). En conséquence, le code ci-dessus affichera la valeur 10 puis la valeur 20! Si une variable est de type référence, il est possible d'indiquer qu'elle ne se réfère à aucun objet en lui affectant explicitement la valeur null. Conclusion Types Valeur En C# les types de données de base comme bool ou long sont des types valeur. Autrement dit, si nous déclarons une variable bool et lui affectons la valeur d'une autre variable bool, nous aurons deux variables bool séparées en mémoire. Si par la suite nous modifions la valeur de la variable originale bool, la valeur de la seconde variable bool ne sera pas modifiée. On dit que ces types sont copiés par valeur Types Référence La plupart des types C# plus complexes, y compris les classes que nous déclarons, sont de type référence. Ils sont alloués sur le tas, ont une durée de vie qui peut s'étaler sur plusieurs appels de fonctions, et sont accessibles via un ou plusieurs alias. Le CLR (Common Language RunTime) implémente un algorithme élaboré pour détecter les variables de type référence qui sont encore accessible mais devenues orphelines. Périodiquement, le CLT "nettoie" la mémoire en détruisant les objets orphelins et rend au système d'exploitation la mémoire que ces objets occuppaient. Cette opération de nettoyage s'effectue grâce au "ramasse-miettes" (ou GarbageCollector). Il n'est pas possible de prédire quand le ramasse-miettes va se mettre en action pour réclamer la mémoire qui n'est plus utilisée. On appelle cette manière de nettoyer la mémoire la finalisation non-déterministe. Nous étudierons en détail le mécanisme de nettoyage et ses implications dans le chapitre traitant des constructeurs et destructeurs des classes. Performances 44

45 En définissant les types "primaires" comme int et bool comme des types valeur et les types de plus grande taille contenant de nombreux champs (comme la plupart des classes) comme des types référence, C# assure de hautes performances. 45

46 4.2 Types du Common Type System Les types de base prédéfinis reconnus par la langage C# ne sont pas intrinsèques au langage mais sont en fait des traductions de types "génériques" appartenant au Framework.net. Ceci permet en fait que chaque langage du Framework possède ses propres noms pour ses types de données, mais, "derrière les fagots", c'est toujours un type standard du Framework qui est déclaré. Par exemple, lorsque nous déclarons en C# une variable de type int, c'est en réalité une instance du type CTS System.Int32 du framework qui est déclarée. Passons maintenant en revue les types définis en C#. Nous allons énumérer chaque, type avec sa définition et le type CTS.net correspondant. C# possède quinze types prédéfinis : - 13 types Valeur - 2 Types Référence 4.3 Types Valeur prédéfinis Les types Valeur prédéfinis représentent tous des types primaires, tels que les nombres entiers ou à virgule flottante, les caractères (attention : pas les chaînes), et les types booléens. Types d'entiers C# propose les huit types d'entiers suivants : Nom Type CTS Description Plage (min/max) sbyte System.Sbyte Entier signé sur 8 bits -2 7 : short System.Int16 Entier signé sur 16 bits : int System.Int32 Entier signé sur 32 bits : long System.Int64 Entier signé sur 64 bits : byte System.Byte Entier non-signé sur 8 bits 0 : ushort System.Uint16 Entier non-signé sur 16 bits 0 : uint System.Uint32 Entier non-signé sur 32 bits 0 : ulong System.Uint64 Entier non-signé sur 64 bits 0 : Note: Le type Byte est le type standard sur 8 bits donnant uneplage de valeur de 0 à 255 compris. C# met l'accent sur la sécurité des types en considérant le type byte et le type char comme distincts (alors qu'ils représentent la même plage de valeurs). Dans du code, toute conversion entre ces deux types doit être explicitement demandée. En outre, contrairement aux autres membres de la famille des entiers, le type byte est non-signé par défaut. Sa version signée porte un nom spécial : sbyte. S'il existe une ambiguité quelconque sur la nature d'un entier int, uint ou long, il est remplacé par défaut par int. Pour spécifier à quel type d'entier la valeur doit être associée, nous pouvons attacher l'un des caractères suivants au nombre : uint ui = 1234U; long l = 1234L; ulong ul = 1234UL; 46

47 Types de nombres en virgule flottante Voici les deux types de données C# en virgule flottante : Nom Type CTS Description Plage (min/max) float System.Single Virgule flottante sur 32 bits +/- 1,5 x à simple précision +/- 3,4 x double System.Double Virgule flottante sur 32 bits +/- 5,0 x à double précision +/- 1,7 x Le type float comporte 7 chiffres significatifs après la virgule. Le type double comporte 15 chiffres significatifs après la virgule. Le type de données float permet de manipuler des nombres en virgule flottante pour lesquels une précision normale est requise. Le type de données double est plus volumineux que float mais il offre une précision accrue derrière la virgule (sur 15 chiffres) Si nous codons en "dur" un nombre décimal (comme 15,4) dans le code, le compilateur suppose par défaut que nous souhaitons définir une valeur de type double. Pour indiquer que nous voulons une valeur de type float, il faut lui ajouter le suffixe "F" (ou "f"). float f = 15,4F; Type Decimal Le type decimal comporte 28 chiffres significatifs après la virgule. Nom Type CTS Description Plage (min/max) decimal System.Decimal Virgule flottante sur 128 bits +/- 1,0 x à simple précision +/- 7,9 x Le type decimal est principalement dédié aux calculs financiers. Le mode d'utilisation des 28 chiffres significatifs offert par le type décimal dépend de vous. En d'autres termes, nous pouvons suivre de petits montants en uros avec une très grande précision au niveau des fractions de centimes, ou bien définir de grands montants avec une partie décimale arrondie. Pour spécifier q'une nombre est de type décimal, plutôt que de type double ou float, nous pouvons lui attribuer le suffixe "M" (ou "m"), comme ceci. decimal d = 12.30M; 47

48 Type bool (Booléen) Le type bool de C# contient soit la valeur true soit la valeur false. Nom Type CTS Description Valeurs admises bool System.Boolean booléen true / false Il est important de noter qu'il est impossible de convertir implicitement les valeurs de type bool en entiers (comme cela est possible avec d'autres langages). Si une variable (ou le type renvoyé par une fonction) est de type bool nous ne pourrons utiliser que les valeurs true ou false. Type Char (caractère) Pour stocker la valeur d'un caractère, C# propose le type char. Nom Type CTS Description Valeurs admises char System.Char un seul caractère un seul caractère sur 16 bits ASCII et Unicode : Bien que 8 bits soient suffisants pour encoder chaque caractère de l'anglais, ils ne suffisent pas pour encoder chaque caractère des systèmes alphabétiques utilisant une gamme de symboles plus vaste (comme le chinois par exemple). Dans un souci d'internationalisation, le monde informatique abandonne progressivement l'habitude de stocker les caractères sur 8 bits (ASCII) pour se tourner vers le schéma Unicode normalisé sur 16 bits. A noter qu'ascii est un sous-ensemble d'unicode. Les expressions littérales de type char doivent être placées entre quotes à la différence des chaînes de caractères ou string qui doivent être placées entre guillemets doubles. char c = 'a'; Il est possible de représenter les expressions char sous forme littérale, mais également sous forme de valeurs Unicode hexadécimales à 4 chiffres (par exemple '\u0041'), sous forme de valeurs entières avec un transtypage (par exemple (char)65 ) ou sous forme hexadécimale ( par exemple '\x0041'), ou encore à l'aide d'une séquence d'échappement (escape sequence). La liste des caractère d'échappement est diponible dans l'annexe de ce support nommée "caractères d'échappement" 48

49 4.4 Types Référence prédéfinis C# prend en charge deux types valeurs prédéfinis : Nom Type CTS Description object System.Object Le type racine à partir duquel tous les types dérivent (y compris les types valeurs mais pas directement) string System.String Chaîne de caractères Unicode. Type object En C#, tout est objet. Voici une vérité que nous découvrirons au fur et à mesure de notre apprentissage du language. De nombreux langages et hiérarchies de classes fournissent un type racine, à partir duquel dérivent tous les autres objets de la hiérarchie. En C# le type object est le type racine de tous les types de données. Tous les types de données intrinsèques et les types définis par l'utilisateur dérivent de object. C'est une des caractéristiques clé de C#, qui le distingue de langages comme VB6 ou C++, et le rapproche de Java. Comme tous les types dérivent implicitement de la classe System.Object, nous pouvons utiliser le type object dans un boucle but : - pour établir un lien à un objet d'un sous-type particulier. Par exemple, nous verrons plus loin comment utiliser le type object pour "emboiter" (boxing) un type valeur stocké sur la pile et le déplacer sur le tas. - Pour implémenter un certain nombre de méthodes génériques que tous les éléments de tous les types de données posséderont. C'est le cas des méthodes Equals(), GetHashCode et ToString(). Les classes définies par l'utilisateur peuvent avoir besoin de fournir des implémentations de remplacement de certaines de ces méthodes à l'aide de la technique orientée objet appelée "substitution". Quand nous nous substituons la méthode ToString() par exemple, nous dotons notre classe d'une méthode destinée à fournir une représentation littérale personalisée d'elle-même. Si nous ne fournissons pas notre propre implémentation des ces méthodes dans nos classes, le compilateur appellera les méthodes génériques de la classe object, ce qui peut être pratique dans de nombreux cas. PAS DE CONFUSION! nous avons dit plus haut que tous les types dérivent de System.Object. Pour autant, il ne faut pas en déduire que tous les types de données intrinsèques se comportent comme des objets!!. Il s'agit ici de l'implémentation interne de C#. En réalité, tous les types référence dérivent directement de System.Object, et tous les types valeur dérivent indirectement de System.ValueType qui lui-même dérive de System.Object. 49

50 Type string C# fournit son propre type string. Avec ce type, les opération comme la concaténation ou la copie de chaînes de caractères (et bien d'autres opérations) sont d'une grande simplicité : string s1 = "bonjour "; string s2 = "tout le monde!"; string s3 = s1 + s2; // s3 vaut "Bonjour tout le monde!" Nota Bene : En dépit de ce style d'affectation, la classe CTS System.String est bien un type référence! En coulisses, un objet string, est alloué au tas et non à la pile. Quand nous affectons une valeur littérale à une autre chaîne, nous obtenons deux références à la même chaîne en mémoire. Cependant, si nous modifions l'une de ces chaînes, la modification a pour résultat la création en mémoire d'un nouvel objet string, en laissant l'autre chaîne inchangée. Exemple : using System; namespace CSharp.DataTypes public class StringExemple public static void Main() string s1 = "toto"; string s2 = s1; Console.WriteLine("s1 vaut :" + s1); Console.WriteLine("s2 vaut :" + s2); s1 = "titi"; Console.WriteLine("s1 vaut maintenant :" + s1); Console.WriteLine("s2 vaut maintenant :" + s2); la sortie est la suivante : s1 vaut : toto s2 vaut : toto s1 vaut maintenant : titi s2 vaut maintenant : toto En d'autres termes, la modification de la valeur s1 n'a pas d'effet sur la valeur de s2 contrairement à ce que nous pouvions imaginer avec un type référence!! Que se passe-t-il en réalité? Quand s1 est initialisée avec la valeur "une chaine", un nouvel object est alloué sur le tas. Quand s2 est initialisée, la référence point sur le même objet et a donc également la valeur "une chaîne". 50

51 Cependant, quand nous modifions la valeur de s1, au lien du remplacement de la valeur d'origine, un nouvel objet est créé sur au tas avec la nouvelle valeur. La variable s2 pointe vers l'objet original et sa valeur reste inchangée. Ceci est dû au fait que le type System.String est un type dit "immutable" d'une part. D'autre part l'opérateur d'égalité a été redéfini pour les variables de type string de façon à comparer les valeurs et non les références (en effet, ce comportement est plus "naturel" pour les programmeurs). Chaînes littérales ou "verbatim" Les chaînes C# peuvent, comme les variables char, contenir des séquences d'échappement Unicode et hexadécimales. Comme ces séquences démarrent par le caractère "\", nous ne pouvons utiliser ce caractère une seule fois dans une chaîne. En conséquence (par exemple pour stocker un chemin de fichier) il nous faut mettre deux caractères "\" pour en représenter un : string filepath = "C\\Dev\\TestString.cs"; On peut s'affranchir de cette contrainte car C# nous fournit une alternative : les chaînes littérales ou "verbatim": en préfixant la valeur littérale de la chaîne par le caractère "@" : string filepath lorsqu'une chaîne est préfixée avec le caractère "@" tous ses caractères sont traités comme tels et non comme des séquences d'échappement. Ceci nous permet entre autres choses d'insérer des retours à la ligne dans les expressions littérales : string machainesurdeuxlignes = "Je suis une chaîne avec un retour chariot"; la valeur de la chaîne sera alors : Je suis une chaîne avec un retour chariot 51

52 5. opérateurs et expressions Nous avons maintenant vu comment déclarer et initialiser des variables. Etudions à présent la façon de les manipuler. C# comporte un certain nombre d'opérateurs (dont par exemple l'opérateur d'affectation = que nous avons déjà évoqué dans ce support). La combinaison d'operateurs avec des variables avec des variables et des valeurs littérales permet de créer des expressions, qui sont les composantes de base des calculs. 5.1 Différents types d'opérateurs C# prend en charge les opérateurs décrits dans le tableau suivant. Quatre d'entre eux (sizeof, *, ->, et &) ne sont disponibles que dans du code non-sécurisé (ou "unsafe code"), c'est-à-dire du code qui échappe à la vérification de la sécurité de types de C#. Catégorie d'opérateurs Opérateurs Arithmétique + - * / % Logique & ^ ~ && Concaténation de chaînes + Incrément et décrément Déplacement de bits << >> Comparaison ==!= < > <= >= Affectation = += -= *= /= %= &= = ^= <<= >>= Accès aux membres (pour objets et structures). Indexation (pour tableaux et indexeurs) [] Transtypage () Conditionnel (opérateur ternaire)?: Création d'objets new Informations de type sizeof (non sécurisé) typeof is as Contrôle d'exception de dépassement de pile checked unchecked Indirection et adresses * -> & (non sécurisés) 52

53 5.2 Opérateurs et raccourcis Le tableau suivant donne une liste complète d'opérateurs disponibles en C#. Raccourci de l'opérateur Equivalent à x++, ++x x = x + 1 x--, --x x = x 1 x += y x = x + y x -= y x = x y x *= y x = x * y x /= y x = x / y x %= y x = x % y x >>= y x = x >> y x <<= y x = x << y x &= y x = x & y x = y x = x y x ^= y x = x ^ y L'opérateur d'incrémentation ++ et de décrémentation se placent soit avant l'expression (ils sont alors préfixés) soit après l'expression (ils sont alors suffixés). Les expressions x++ et ++x sont toutes deux équivalentes à : x = x + 1 mais leurs comportement diffèrent. Occupant une ligne, ils sont équivalents et correspondent à l'instruction x = x + 1. La différence apparaît lorsqu'ils sont utilisés dans des expressions : ++x incrémente la valeur de x avant que l'expression soit évaluée; en d'autres termes, x est d'abord incrémenté, puis la nouvelle valeur de x est utilisée dans l'expression x++ incrémente la valeur de x après que l'expression a été évaluée, ce qui fait que l'expression est d'abord évaluée avec la valeur initiale de x et l'incrémentation de x se fait seulement après. L'exemple suivant montre la différence entre les deux opérateurs : int x = 5; if (++x == 6) Console.WriteLine("Cette ligne sera exécutée"); if (x++ == 7) Console.WriteLine("Cette ligne ne sera PAS exécutée"); 53

54 5.3 L'operateur ternaire L'opérateur ternaire?: est une forme abrégée de la construction if..else. Il tient son nom du fait qu'il implique trois opérandes. Il permet d'évaluer une condition en retournant une valeur si cette condition est vraie et une autre valeur si cette condition est fausse. Syntaxe : condition? valsivrai : valsifaux Il est préférable d'utiliser cet opérateur avec modération et lui préférer dans la plupart des cas des structures conditionnelles if..else classiques. Cependant, il permet quelquefois de rendre plus concises quelques lignes de code. En voici un exemple : bool condition = true; Console.WriteLine(condition? "Vrai" : "Faux"); Le code ci-dessus écrit "Vrai" dans la sortie. 5.4 Opérateurs checked et unchecked Les opérateurs checked et unchecked permettent de mettre en œuvre ou d'empêcher les contrôles de dépassement par le compilateur. Regardons le code suivant : byte b = 255; b++; Console.WriteLine(b.ToString()); Le type de données byte ne peut contenir que des valeurs dans la plage allant de 0 à 255. L'incrémentation de la valeur de b avec b++; déclenche donc un dépassement de pile. La manière dont le CLR traite ce problème dépend de divers paramètres dont (entre autres) les options que l'utilisateur a défini pour le compilateur. Normalement, à chaque fois que du code peut déclencher un dépassement non autorisé, il faut s'assurer d'obtenir le résultat désiré. Pour ce faire, C# nous fournir les opérateurs checked et unchecked. Si nous marquons un bloc de code comme checked, le CLR active le contrôle de dépassement pour ce bloc et lève une exception si un dépassement survient dans ce bloc. Si nous modifions le code pour l'encadrer dans un bloc checked : byte b = 255; checked b++; Console.WriteLine(b.ToString()); Si nous lançons ce code, nous obtenons un message d'erreur nous indiquant qu'un exception de type System.OverflowException s'est produite. Si nous souhaitons supprimer le contrôle de dépassement pour ce bloc de code, nous pouvons au contraire marquer le bloc comme unchecked. Dans ce cas, aucune exception n'est levée, mais nous perdrons des 54

55 données car le type byte ne peut pas contenir la valeur 256. Les bits du dépassement sont supprimés et la variable b contiendra la valeur zéro. NB1: Vous pouvez mettre en œuvre le contrôle de dépassement pour tout votre code non marqué comme checked en compilant avec l'option /checked. Attention : code comme checked. unchecked est le comportement par défaut! En d'autres termes, cet opérateur est rarement utilisé explicitement, sauf quand il nous faut marquer quelques lignes de unchecked dans un grands bloc de code explicitement marqué comme 5.5 Opérateur sizeof Nous pouvons déterminer la taille (en octets) requise par un type valeur de la pile en utilisant l opérateur sizeof : unsafe Console.WriteLine(sizeof(int)); 5.6 Opérateur typeof L opérateur typeof retourne un objet Type représentant un type spécifié. Par exemple, typeof(string) retourne un objet représentant le type System.String. C est utile lorsque nous voulons exploiter la réflexion pour obtenir dynamiquement des informations sur un objet (notons que nous pouvons également utiliser la méthode d'instance typeobjet.gettype()). Nous aborderons la réflexion plus loin dans ce support. 5.7 Préséance des opérateurs Le tableau suivant indique l ordre de priorité des opérateurs C#. Les opérateurs au sommet du tableau sont ceux qui ont la priorité la plus forte (c est à dire, ceux qui sont évalués en premier dans une expression contenant plusieurs opérateurs) : Groupe Divers Unaire Multiplication / Division * / % Addition / Soustraction + - Opérateurs de décalage binaires << >> Opérateurs (). [] x++ x new typeof sizeof checked unchecked + -! ~ ++x x transtypages Relationnel < <= >= > is as Comparaison ==!= ET binaire & OU binaire ^ XOR binaire ET booléen && OU booléen Opérateur ternaire?: Affectation = += -= *= /= %= &= = ^= <<= >>= 55

56 5.8 Sécurité et Types Le langage intermédiaire met en œuvre la sécurité des types dans son code. Le typage fort autorise de nombreux services fournis par.net, dont la sécurité et l interopérabilité des langages. Comme nous pouvons nous y attendre de la part d un langage compilé en IL, C# est également fortement typé. Entre autres, cela signifie que le type bool dédié n est pas converti automatiquement en type entier. Pour opérer une telle conversion, nous devons en faire la demande, à l aide d un transtypage explicite. Dans ce chapitre, nous examinerons le transtypage entre types primaires. 6. Conversions de types de données Nous avons souvent besoin de convertir des données d un type vers un autre. Considérons le type suivant : byte value1 = 10; byte value2 = 20; byte total; total = value1 + value2; Console.WriteLine(total); Si nous compilons ces lignes, nous obtenons le message d erreur : Cannot implicitly convert int to byte Le problème est le suivant : lorsque nous additionnons deux byte, le résultat retourné est un int, et non un autre byte. Cela est dû au fait qu un byte ne peut contenir que huit bits de données. Pour stocker ce résultat dans une variable byte, il faut la reconvertir en un byte. Cela peut se faire implicitement ou explicitement. 6.1 Conversions implicites La conversion entre types peut normalement s effectuer de façon automatique (implicitement) uniquement si nous pouvons garantir, ce faisant, qu elle n affectera en aucune manière la valeur. C est la raison pour laquelle le code précédent provoque une erreur à la compilation : en tentant une conversion d un type int en type byte, nous avons potentiellement perdu trois octets de données. Le compilateur ne le permet pas, à moins que nous lui indiquions explicitement que c est ce que nous voulons faire! Toutefois, si nous stockons le résultat dans un type long au lieu d un type byte, nous n avons aucun problème : // Ce code se compile sans problème. byte value1 = 10; byte value2 = 20; long total; total = value1 + value2; Console.WriteLine(total); Comme un type long renferme plus d octets de données qu un type int, il n y a pas de risque de perte de données et le code se compile sans problème. 56

57 Le tableau suivant liste les conversions de types implicites prises en charge par C# : De sbyte byte short ushort int uint long, ulong float char En short, int, long, float, double, decimal short, ushort, int, uint, long, ulong, float, double, decimal int, long, float, double, decimal int, uint, long, ulong, float, double, decimal long, float, double, decimal long, ulong, float, double, decimal float, double, decimal double ushort, int, uint, long, ulong, float, double, decimal Nous ne pouvons effectuer des conversions implicites que d un entier de petite taille vers un entier de plus grande taille, et non l inverse. Nous pouvons aussi passer d une valeur entière à une valeur en virgule flottante. Outre des conversions entre types de même taille, par exemple de int/uint en float et de long/ulong en double, nous avons également la possibilité d effectuer une conversion inverse de long/ulong en float. Nous pouvons perdre quatre octets de données dans l opération car le type float résultant est moins précis qu un type double. Le compilateur considère cela comme une erreur acceptable, l ordre de grandeur de la valeur n en étant pas affecté. Nous pouvons également affecter une variable non signée à une variable signée à condition que les limites de valeur du type non signé rentrent dans les limites de la variable signée. 57

58 6.2 Conversions explicites De nombreuses conversions ne peuvent être effectuées implicitement entre types. En cas de tentative de ce genre, le compilateur renvoie une erreur. Voici quelques transformations qui ne peuvent être effectuées implicitement : - de int en short (risque de perte de données) ; - de int en uint (risque de perte de données) ; - de uint en int (risque de perte de données) ; - de float en int (perte de tout ce qui se trouve après le point décimal) ; - de tout type numérique en char (risque de perte de données) ; - de decimal en n importe quel type numérique, le type decimal étant structuré en interne différemment des entiers et des nombres en virgule flottante. Cependant, nous pouvons effectuer explicitement de telles transformations en utilisant le transtypage. Lorsque nous transtypons un type dans un autre, nous forçons délibérément le compilateur à effectuer la transformation. Un transtypage ressemble à ceci : long val = 30000; int i = int(val); Nous indiquons le type que nous transtypons en plaçant le type transtypé entre parenthèses avant la valeur à modifier. Pour les programmeurs en C, cette syntaxe de transtypage est habituelle. Cesl pérations sont potientiellement dangereuse : même un transtypage de long en int peut entraîner des problèmes si la valeur initiale dépasse la valeur maximale d'un int. long val = ; int i = (int)val; // transtypage invalide : valeur max de int : Dans le code précédent, nous n'obtenons pas d'erreurs explicite, mais nous n'avons pas non plus la valeur attendue dans la variable int, nous obtenons : En fait, il ne faut jamais supposer a priori que le transtypage fournira le résultat attendu. C# propose un opérateur checked qui permet de tester si une opération provoque un dépassement. Nous pouvons utiliser cet opérateur pour vérifier qu un transtypage est sûr et forcer le runtime à lever une exception de dépassement en cas de besoin : long val = ; int i = checked((int)val); // ici une exception System.OverflowException est levée Avec le transtypage, nous pouvons convertir la plupart des types de données d un type dans un autre, par exemple : double prix = 25.30; int prixarrondi = (int)(price + 0.5); Dans l'exemple ci-dessus, nous obtenons la valeur arrondie. 58

59 Cet exemple montre ce qui se passe lorsque nous convertissons un entier non signé dans le type char : ushort c = 43; char symbol = (char)c; Console.WriteLine(symbol); La sortie correspond au caractère ayant le code ASCII 43, à savoir le signe +. Nous pouvons tenter tout type de transformation entre les types numériques (dont char), aussi étonnant que cela puisse paraître. Ainsi, la conversion d un type decimal en type char fonctionne, et vice versa. Cependant, si la valeur qui résulte de l opération de transtypage ne peut pas s ajuster au nouveau type de données, le transtypage semble fonctionner mais le résultat n est pas nécessairement celui attendu. Par exemple : int i = -1; char c = (char)i; Ce transtypage ne devrait pas fonctionner car le type char ne peut accepter de valeurs négatives. Cependant, nous n obtenons pas d erreur et la valeur? est affectée à la variable symbol. Pour effectuer une conversion entre un nombre et une chaîne, par exemple, nous disposons des méthodes offertes par la bibliothèque de classes de.net. La classe object implémente une méthode ToString(), qui a été remplacée dans tous les types.net prédéfinis et qui retourne une représentation littérale de l objet : int i = 10; string s = i.tostring(); Pour «parser» une chaîne afin de retrouver une valeur numérique ou booléenne, nous pouvons utiliser la méthode Parse() prise en compte par tous les types valeur prédéfinis : string s = "100"; int i = Int.Parse(s); Console.WriteLine(i + 50); La méthode statique Parse lève une exception si elle n'est pas capable de convertir la chaîne. 59

60 6.3 Boxing et un-boxing Tous les types, aussi bien les types simples prédéfinis comme int et char que les types complexes tels que les classes et les structures, dérivent du type object. Cela signifie que nous pouvons traiter des valeurs littérales comme si elles étaient des objets : string s = 10.ToString(); Par ailleurs, les types de données de C# se divisent entre les types valeur, alloués à la pile, et les types référence, alloués au tas. Comment cela cadre-t-il avec la possibilité d appeler les méthodes sur int, si int n est rien de plus qu une valeur sur quatre octets de la pile? C# réalise en fait un tour de passe-passe appelé boxing (emboîtage). Boxing et un boxing (déboîtage) permettent de convertir des types valeur en types référence, et vice versa. Ces opérations s apparentent au transtypage en ce sens que nous transtypons une valeur en type object. "Boxing" est un terme utilisé pour décrire la transformation d un type valeur en type référence. Pour ce faire, le runtime crée une «boîte»temporaire de type référence pour l objet sur le tas. Cette conversion peut avoir lieu implicitement, comme dans l exemple précedent, mais elle peut aussi être effectuée manuellement : int i = 20; object o = i; "Unboxing" (déboîtage) est le terme utilisé pour décrire le processus inverse, par lequel une valeur d un type référence est transtypée en type valeur. Nous utilisons le terme «transtypage» ici, car cela doit être fait explicitement. La syntaxe est comparable à celle des conversions de types explicites déjà écrites : int i = 20; object o = i; int j = (int)o; Attention : lors du déboîtage, il faut veiller à ce que la variable réceptrice de la valeur ait suffisamment d espace pour stocker tous les octets dans la valeur déboîtée. Les types int de C#, par exemple, ont une longueur de 32 bits, de sorte que le déboîtage d une valeur long (sur 64 bits) en un int entraîne une exception InvalidCastException, comme dans l exemple suivant : long a = ; object b = (object)a; int c = (int)b; 60

61 7. Contrôle du Flux d'exécution Dans cette section, nous allons examiner le processus de fonctionnement du langage eet en particulier les instructions qui permettent de contrôler le flux d'exécution d'un programme. 7.1 Les Instruction Conditionnelles Les instructions conditionnelles permettent d'insérer des branchements dans le code selon que certaines conditions sont vérifiées ou pas ou encore en fonction de la valeur d'une expression. La langage C# possède deux structures conditionnelles : l'instruction if qui permet de tester si une condition est satisfaite et l'instruction switch qui permet de comparer une expression avec différentes valeurs et d'effectuer des actions en conséquence. L'instruction if Pour les branchements conditionnels, C# utilise la même syntaxe pour l'instruction if que C et C++. Voici les différentes formes syntaxiques de l'instruction if : Evaluer une seule condition if (condition) instruction; Par exemple : if (x > 5) Console.WriteLine("x est supérieur à 5); Si plusieurs instructions doivent être exécutées lorsque la condition est vérifiée, il faut encadrer le bloc d'instruction entre des accolades : if (condition) instruction1; instruction2; Remarque : il est plus "propre" (voir annexe "conventions de codage") de toujours encadrer les instructions dépendantes d'une conditions dans un bloc d'accolades. Ne pas le faire n'est pas illégal mais peut rendre la lecture du code plus difficile. Par exemple : if (x == 0) Console.WriteLine ("X est égal à 0"); Console.WriteLine ("X peut être n'importe quelle valeur"); Dans l'exemple précédent, la ligne indiquant que "x peut être n'importe quelle valeur" s'exécutera toujours quelle que soit la valeur de x. et ne dépendra donc pas du résultat de l'évaluation de la condition 61

62 Il aurait été plus facile de lire : if (x == 0) Console.WriteLine ("X est égal à 0"); Console.Write ("ligne non dépendant du test x == 0"); Evaluer deux jeux de résultats On peut également vouloir effectuer deux actions différentes selon que la condition dans le test if est vérifiée ou pas. Dans ce cas, on utilise la clause else des manières suivante : Pour exécuter plusieurs instructions dans chaque bloc if (condition) instructions; else instructions; Pour n'exécuter qu'une instruction par bloc if (condition) instruction; else instruction; Evaluer des jeux de résultats multiples On peut également avec la structure if souhaiter évaluer plusieurs conditions (et non pas seulement une condition qui est soit vraie soit fausse). Dans ce cas, on dipose de la clause else if qui nous permet d'ajouter des conditions à tester. string reponse; reponse = Console.ReadLine(); // Lit l'entrée de l'utilisateur if (reponse.length == 0) Console.WriteLine("Vous n'avez pas entré de texte"); else if (reponse.length < 5) Console.WriteLine("Vous avez pas entré moins de 5 caractères"); else if (reponse.length < 10) Console.WriteLine("Vous avez pas entré entre 5 et 10 caractères"); else Console.WriteLine("Vous avez entré plus de 10 caractères"); Notons que la clause else n'est pas obligatoire lors de l'utilisation de clauses else if. Le nombre de clauses else if pouvant être ajoutées à la clause if initiale n'est pas limité, cependant, lorsque nous souhaiterons évaluer un grand nombre de jeux de résultats possibles différents, on utilisera (autant que possible) l'instruction switch.. case qui est plus lisible. 62

63 L'instruction switch L'instruction switch.. case est apte est apte à sélectionner un branchement de l'exécution à partir d'un jeu de branchement mutuellement exclusifs. Cette instruction est connue des programmeurs C++ et Java. Les programmeurs VB la connaissent sous la forme presque identique de l'instruction Select.. Case. Syntaxe de switch case Cette instruction prend la forme d'un argument switch, suivi d'une série de clauses case. Lorsque l'expression de l'argument switch s'évalue à l'une des valeurs placées dans les clauses case, le bloc d'instructions situé immédiatement en dessous de la clause case est exécuté. Dans ce cas, nous n'avons pas besoin de mettre les instructions dépendantes d'un bloc case entre accolades, mais nous devons indiquer la fin du code de chaque clause case par le mot-clé break suivi d'un point virgule. Nous pouvons également inclure dans une instruction switch une clause default qui sera exécutée si l'expression testée ne s'évalue à aucune des clause case. L'instruction switch teste ici la valeur de la variable inta (qui est de type int) : switch (inta) case 1: Console.WriteLine("intA vaut 1"); break; case 2: Console.WriteLine("intA vaut 2"); break; case 3: Console.WriteLine("intA vaut 3"); break; default: // Cas par défaut utilisé si aucun bloc case n'est exécuté Console.WriteLine("intA ne vaut ni 1 ni 2 ni 3"); break; Remarque : notons que les valeurs associées aux blocs case doivent être soit des valeur littérales soit des constantes mais ne peuvent pas être des variables. Fall-through Les programmeurs en C et C++ connaissant l'instruction switch avec une syntaxe un peu différente. Cependant, cette instruction est plus sûre en C#. En particulier elle interdit les conditions dites "fall trough" dans presque tous les cas. Autrement dit, si une clause case est activée en début de bloc, les clauses case suivantes ne peuvent plus être activée (à moins d'utiliser l'instruction goto) pour marquer spécifiquement la volonté d'activer une cause particulière. Le compilateur renforce cette restriction en siganalant chaque clause case non pourvue d'une instruction break comme une erreur avec le message d'erreur suivant : Control cannot fall trough from one case label ('case x') to another. Bien que le comportement "fall trough" soit désirable dans un nombre limité de situations, il est involontaire dans la majorité des cas et a pour résultat une erreur logique difficile à cerner. 63

64 Instruction goto En utilisant des instructions goto (cette approche n'est pas très structurée mais c'est quelquefois la seule approche), il est possible de simuler la fonctionnalité "fall-through" dans les instructions switch case. Cette approche n'est pas élégante. Le code suivant démontre la manière d'utiliser goto pour simuler un fallthrough; il montre également combien le code résultant peut être "touffu" (on appelle également ce genre de code difficile à lire du code "spaghetti"). // on suppose que le pays (country) et la langue (langage) sont de type string switch (country) case "America": CallAmericanMethod; goto case "Britain"; // Aller au bloc case "Britain" case "France": langage = "French"; break; case "Britain": langage = "English"; break; Il existe toutefois une exception à la règle "no fall-through" : Il est en fait possible de passer directement d'une clause case à une autre si cette clause est vide. Cela permet de traiter deux clauses case ou plus de manière identique sans faire appel à des instructions goto. switch (country) case "us": case "uk": case "au": langage = "English"; break; case "ca": case "fr": langage = "French"; break; Important : Un aspect curieux de C# est que l'ordre des clauses case n'a pas d'importance et il est même possible de placer la clause default en premier! Il en résulte que deux clauses case ne peuvent pas être identiques! Cela concerne par exemple des constantes différentes mais ayant la même valeur. Ainsi, le code suivant est dont incorrect : const string england = "uk"; const string britain = "uk"; switch (country) case england: case britain: language = "English"; 64

65 break; 7.2 Les Boucles C# propose quatre types de boucles différentes (for, while, do while et foreach) permettant de répéter l'exécution d'un bloc de code jusqu'à ce qu'un condition soit satisfaite. Les boucles for, while et do while sont pour l'essentiel indentiques à celles utilisées en C++. Nous allons examiner en détail le fonctionnement de chacune de ces boucles. La boucle for Les boucles for de C# proposent un mecanisme d'itération qui teste si une condition est remplie avant d'effectuer une autre itération (une itération est un passage complet dans le corps de la boucle). syntaxe de la boucle for : for (intialiseur; condition; itérateur) instruction(s) où : - L'initialiseur est l'expression évaluée avant l'exécution de la première boucle (en général c'est une variable locale servant de compteur de boucle) - La condition est l'expression vérifiée avant chaque nouvelle itération de la boucle (elle doit être évaluée à la valeur true pour qu'une autre itération puisse être effectuée) - L'itérateur est une expression qui est évaluée après chaque itération, réalisant habituellement l'incrémentation du compteur de boucle). Les itérations cessent dès que la condition est évaluée à la valeur false. La boucle for est une boucle dite de "pre-test" car la condition de la boucle est évaluée avant que les instructions de boucle soient exécutées. La boucle for est tout à fait adaptée pour répéter une ou plusieurs instructions pendant un nombre déterminé de fois. L'exemple de code suivant est typique d'un boucle for. Ce code affiche les valeurs de 0 à 10 : for (int i = 0; i < 11; i++) Console.WriteLine(i); Nous déclarons ici une variable int nommée i et nous l'initialisons à zéro. Elle sera utilisée comme compteur de boucle. Nous testons immédiatement si elle est inférieure à 11. Comme cette condition s'évalue à true, le code dans la boucle s'exécute, ce qui permet d'imprimer la valeur 0 (à la première itération bien sûr). Nous incrémentons ensuite le compteur de 1 et le processus reprend. La boucle se termine quand la variable i a atteint la valeur

66 La syntaxe de la boucle for en C# est bien plus puissante que la syntaxe For Next de VB car l'itérateur peut être n'importe quelle instruction. En VB, tout ce qu'il est possible de faire est d'ajouter ou de soustraire un nombre à la variable de contrôle de la boucle. En C# tout est permis, y compris multiplier la variable de contrôle par un autre nombre. 66

67 La boucle while la boucle while est identique à la boucle while en C++ et en Java et à la boucle While Wend en VB. Comme la boucle for, la boucle while est une boucle de pré-test. Leur syntaxe est similaire mais la boucle while n'admet qu'une seule expression de condition. syntaxe de la boucle while : while (condition) instruction(s) Contrairement à la boucle for, la boucle while est le plus souvent utillisée pour répéter les instructions contenues dans son bloc un nombre de fois qui n'est pas connu avant que la boucle commence. Habituellement, une instruction dans le corps de la boucle while définit un flag booléen à false sur une certaine itération, déclenchant ainsi la fin de la boucle, comme dans l'exemple suivant : bool condition = false; while (condition) // cette boucle tourne jusqu'à ce que : condition soit égal à true FaireLeJob(); // On suppose que la méthode VerifierCondition renvoie du bool condition = VerifierCondition(); Toutes les structures de boucles de C# peuvent renoncer aux accolades encerclant le bloc de code si elles ne contiennent qu'une seule instruction. La boucle do while La boucle do..while est la version "post-test" de la boucle while. La condition de test de la boucle est évaluée après l'exécution du corps de la boucle. En conséquence, les boucles do..while sont utiles dans les situations dans lesquelles le corps de la boucle doit être exécuté au moins une fois. syntaxe de la boucle do..while : do instruction(s) while (condition); exemple : do // cette boucle au moins une fois même si condition = false FaireLeJob(); // On suppose que la méthode VerifierCondition renvoie du bool condition = VerifierCondition(); 67

68 while (condition); La boucle foreach La boucle foreach est la dernière structure de boucle disponible en C#. Cette structure de boucle a été empruntée au langage VB, et n'existait pas dans C++ ni dans Java. La boucle foreach permet de procéder par itérations dans les éléments d'une collection. Pour l'instant, nous ne définirons pas en détail ce qu'est une collection (nous le verrons en détail plus loin dans ce support). Disons simplement qu'il s'agit d'un objet pouvant contenir d'autre objets dans une sorte de liste. Techniquement, pour être admis comme collection par le Framework.net, un objet doit prendre en charge une interface nommée IEnumerable. Comme exemples de collections, citons les tableaux C#, les classes de collections définies dans les espaces de nom System.Collections et System.Collections.Specialized et les classes de collection définies par les utilisateurs. Le code suivant donne un aperçu de la syntaxe de la boucle foreach : // Déclaration et initialisation d'un tableau de int avec les valeurs 1,2,3,4 et 5 int[] tableauint = 0,1,2,3,4,5; foreach (int temp in tableauint) Console.WriteLine(temp); Ici, la boucle foreach parcourt le tableau tableauint élément par élément. Pour chaque élément (donc à chaque itération), elle place la valeur de l'élément dans la variable temp de type int et effectue une itération dans la boucle. Attention : avec la structure de boucle foreach, il n'est pas possible de modifier la valeur d'un élément de la collection (représenté par la valriable temp dans cet exemple) depuis le corps de la boucle. Ainsi le code suivant est incorrect et ne peut pas être compilé : // Déclaration et initialisation d'un tableau de int avec les valeurs 1,2,3,4 et 5 int[] tableauint = 0,1,2,3,4,5; foreach (int temp in tableauint) temp++; Console.WriteLine(temp); Nous apprendrons plus loin dans ce cours comment utiliser et créer des objets collections sur lesquels nous pourrons itérer avec la syntaxe de boucle foreach. Il est intéressant de noter que de telles classes écrites en C# peuvent également être parcourues avec la syntaxe For Each.. Next de Visual Basic.net. 68

69 7.3 Instruction de saut C# fournit un certain nombre d'instructions qui permettent de "sauter" immédiatement à une autre ligne de code. La première de celles-ci est bien sûr la (tristement) célèbre instruction goto. L'instruction goto L'instruction goto permet de sauter directement à une ligne de programme spécifiée, identifiée par une étiquette. Une étiquette est un identifiant seul sur une ligne suivi d'un caractère deux-points. Syntaxe et exemple : goto Label1; Console.WriteLine("Cette ligne n'est pas exécutée"); Label1: Console.WriteLine("Cette ligne est exécutée après le goto"); Il existe certaines restrictions concernant l'instruction goto : - Il n'est pas possible de sauter à un bloc de code tel qu'une boucle for. - Il n'est pas possible de sauter en dehors d'une classe. - Il n'est pas possible de s'échapper d'un bloc de gestion d'erreur try..catch..finally L'utilisatiion de goto (en général) ne se conforme pas aux règles d'une programmation objet bien structurée. Cependant, il existe des cas dans lesquels il est admis de l'utiliser (comme nous l'avons déjà vu dans l'instruction switch..case) L'instruction break Nous avons déjà utilisé une instruction break pour sortir d'une clause case dans une instruction switch. En fait, l'instruction break peut également être utilisée pour sortir prématurément des boucles for, foreach, while ou encore do while. Le contrôle est alors transféré juste après la fin de la boucle. Si l' instruction break apparaît dans une boucle imbriquée, le contrôle est transféré à la fin de la boucle la plus interne. Si l' instruction break apparaît en dehors d'une instruction switch ou d'une boucle, une erreur de compilation survient. L'instruction continue L'instruction continue ne peut être utilisée que dans une boucle for, foreach, while ou do..while. Au lieu de quitter la boucle, elle fait sortir de l'itération en cours et passe à l'iteration suivante. L'instruction return L'instruction return est utilisée pour sortir d'une méthode (une fonction) et retourne le contrôle au code appelant. Si la méthode doit renvoyer une valeur, l'instruction return doit être suivie d'une expression de ce type, sinon elle peut être appelée telle quelle. 69

70 3. Chapitre 3 : Structure des programmes 3.1 Les Tableaux en C# Définition Un tableau est une structure indexée qui contient des objets de même type. Les tableaux peuvent posséder une ou plusieurs dimensions. Pour accéder à un élément d'un tableau, il faut spécifier une valeur d'index pour chacune des dimensions du tableau. En C#, tous les tableaux sont de base zéro. Ceci veut dire que l'index du premier élément d'un tableau sera toujours zéro, et par conséquent, l'index du dernier élément d'un tableau sera toujours égal au nombre total d'éléments dans le tableau moins un. En fait, quand nous déclarons un tableau en C#, une instance de la classe System.Array est créée en coulisses, mais les éléments du tableau sont, eux, du type avec lequel vous avez déclaré le tableau Les tableaux à une dimension Voici la syntaxe pour déclarer un tableau à une dimension : <type>[] nomtableau; par exemple : int[] tableauint; Initialisation Pour initialiser un tableau de dimensions spécifiques, il nous faut utiliser le mot-clé new (ce qui confirme qu'en fait, nous instancions un objet de type System.Array) et indiquer au tableau le nombre de cases que cette dimension doit contenir : int[] tableauint; tableauint = new int[3] // Tableau de 3 cases. (index de 0 à 2). on peut également (et c'est souvent assez pratique) grouper la déclaration et l'initialisation sur la même ligne : int[] tableauint = new int[3]; On peut aussi déclarer un tableau et initialiser ses cases avec un contenu littéral en utilisant la syntaxe suivante: int[] tableauint = new int[3] 11, 22, 33; ou encore déclarer un tableau et initialiser ses cases sans employer l'opérateur new avec la syntaxe suivante : 70

71 int[] tableauint = 0, 2, 4, 6, 8, 10 La ligne de code précédente définit un tableau de 6 cases dont les index vont de 0 à 5 et dont les valeurs sont contenues entre les accolades, séparées par des virgules. Notons également qu'il est possible de définir le nombre d'éléments pour une dimension donnée d'un tableau à l'aide d'une variable au lieu d'un littéral : int longueur; longueur = 5; string[] montableau = new string[longueur]; Accès aux éléments du tableau Pour accéder à un élément du tableau, il suffit de préciser pour chaque dimension du tableau à quel index se trouve l'élément : int[] tableauint = 0, 2, 4, 6, 8, 10 int temp = tableauint[2] //temp obtient la valeur Les tableaux à plusieurs dimensions C# prend en charge les tableaux multi-dimensionnels "rectangulaires". Un tableau "rectangulaire" à plusieurs dimensions est un tableau dans lequel chaque ligne a le même nombre de colonnes. Pour déclarer un tableau à plusieurs dimensions, il nous suffit d'insérer une virgule pour séparer les dimensions dans la déclaration du tableau comme ceci : int[,] tableaurect; // Tableau à 2 dimensions int[,,] tableaucube; // Tableau à 3 dimensions Après avoir déclaré un tableau multidimensionnel, on peut l'initialiser en spécifiant la taille de chacune des dimensions. int[,] tableaurect = new int[3,2]; // Tableau à 3x2 cases int[,] tableaucube = new int[2,2]; // Tableau à 2x2 cases On peut aussi, comme pour les tableaux à une dimension déclarer et initialiser les valeurs contenues dans le tableau en une seule ligne. Par exemple, le code suivant déclare et initialise les valeurs de deux tableaux multidimensionnels de dimensions 2x2 et 3x2 respectivement et définit les valeurs stockées dans chacune de leurs cases int[,] tableaurect = new int[3,2] 1,2,3,4,5,6; string[,] noms = new string[2,2] "aa","bb","cc","dd"; Il possible de ne pas spécifier explicitement la taille des tableaux, auquel cas leur taille dépendra du nombre d'élements littéraux qui leur seront alloués. Voici les mêmes tableaux que précédemment : int[,] tableaurect = new int[,] 1,2,3,4,5,6; string[,] noms = new string[2,2] "aa","bb","cc","dd"; 71

72 // ou encore.. int[,] tableaurect = 1,2,3,4,5,6; string[,] noms = "aa","bb","cc","dd"; Les tableaux orthogonaux (jagged arrays) Le second type de tableau multi-dimensionnel que C# prend en charge est le tableau orthogonal ou "jagged array", ou encore tableau de tableaux. Dans un tableau orthogonal, chaque case contient un tableau, ce qui fait que l'on peut avoir des structures non-rectangulaires. Pour déclarer des tableaux de tableaux, on utilise des jeux de crochets avec la syntaxe suivante : Déclaration int[][] jaggedarray; Initialisation Malheureusement, l'initialisation de ces tableaux n'est pas aussi simple que celle des tableaux rectangulaires à plusieurs dimensions. Pour les initialiser, nous avons deux solutions: La première solution consiste à initialiser d'abord le tableau contenant les sous-tableaux, puis les les soustableaux proprement dits : int[][] jaggedarray; jaggedarray = new int[2][]; // init du tableau contenant jaggedarray[0] = new int[3]; // init du sous tableau jaggedarray[1] = new int[4]; // init du sous tableau La deuxième solution consiste à utiliser une forme modifié de l'affectation littérale, comme suit : int[][] jaggedarray; jaggedarray = new int[]0,1,2), new int[]0,1,2,3 72

73 Parcours des tableaux de tableaux Pour accéder aux données des tableaux de tableaux, l'imbrication de boucles for est plus courante que l'usage de boucle foreach. Par exemple, le tableau suivant contient 10 tableaux, qui, à leur tour, contiennent un tableau d'entiers qui sont diviseurs d'un entier entre 1 et 10. int[][] diviseurs1a5 = new int[] 1, new int[] 1, 2, new int[] 1, 3, new int[] 1, 2, 4, new int[] 1, 5, new int[] 1, 2, 3, 6, new int[] 1, 7, new int[] 1, 2, 4, 8, new int[] 1, 3, 9, new int[] 1, 2, 5, 10; si l'on souhaite itérer et imprimer les valeurs du tableau, il faut utiliser soit : Console.WriteLine("Impression des valeurs avec boucle for :\n\n"); for(int x = 0 ; x < diviseurs1a10.length ; x++) for(int y = 0 ; y < diviseurs1a10[x].length ; y++) Console.Write("[0] ",diviseurs1a10[x][y]); Console.Write("\0"); Console.WriteLine(""); soit : Console.WriteLine("Impression des valeurs avec boucle foreach :\n\n"); foreach (int[] diviseursentiers in diviseurs1a10) foreach (int diviseur in diviseursentiers) Console.Write("[0] ",diviseur); Console.WriteLine(); 73

74 3.1.5 La classe Array et ses méthodes. La classe System.Array est la classe de base pour tous les tableaux en C#. Cette classe fournit des méthodes pour manipuler, créer, trier et rechercher des éléments dans les tableaux. Propriétés de System.Array Class IsFixedSize IsReadOnly Length Rank Indique si le tableau a une taille fixe ou pas. Indique si le tableau est en lecture seule. le nombre total d'éléments du tableau, toutes dimensions confondues le nombre de dimensions du tableau. Méthodes de System.Array Class. BinarySearch Clear Copy CopyTo GetEnumerator GetLength GetLowerBound GetUpperBound IndexOf LastIndexOf Reverse Sort Cette méthode recherche un élément dans un tableau à une dimension en utilisant un algorithme de recherche binaire. Supprime tous les éléments du tableau. Cette méthode copie une partie d'un tableau dans un autre tableau. Cette méthode copie tous les éléments du tableau à une dimension en cours dans un autre tableau, en démarrant à l'élément d'index spécifié dans le tableau destination Renvoie un objet IEnumerator pour le tableau Renvoie le nombre d'éléments dans le tableau. Renvoie l'index de base pour la dimension spécifiée. Renvoie l'index supérieur pour la dimension spécifiée. Renvoie l'index de la première occurrence d'une valeur recherchée dans un tableau ou une portion de tableau. Renvoie l'index de la dernière occurrence d'une valeur recherchée dans un tableau ou une portion de tableau. Inverse l'ordre des éléments dans un tableau à une dimension. Trie le tableau (uniquement pour les types intrinsèques ou les types qui implémente Icomparable). 74

75 3.2. Les Enumérations Définition et usage Une énumération est un en fait un jeu de constantes numériques fortement typées. Il existe de nombreux cas dans lesquels une fonction ou une variable doivent recevoir une valeur comprise dans un jeu déterminé de valeurs. Une énumération est un type valeur. Les enumérations remplissent ce rôle. Le Framework.net définit un grand nombre d'énumérations et nous pouvons bien sûr définir nos propres énumérations. Le mot-clé enum permet de définir une énumération avec la syntaxe suivante : enum <nomenum> valeur1, valeur2, valeurx Une fois une énumération définie, on peut déclarer des variable du type de cette énumération avec la syntaxe suivante : <nomenum> nomvar; Les valeurs doivent être attribuées aux variables de type énumérés avec la syntaxe suivante : nomvar = nomenum.valeur; Il est intéressant de noter le support IntelliSense de l'éditeur de Visual Studio, qui nous permet lors de l'affectation d'une valeur à une variable de type énumération, de voir apparaître toutes les valeurs définies dans l'énumération. Ceci évite bien des fautes et permet aux développeurs de ne pas avoir à se souvenir des plages de valeurs acceptées par la variable ou l'élement de type énumération Typage sous-jacent des énumérations Les énumérations possèdent un type sous-jacent nécessaire au stockage des données. Chaque valeur admise par le type énumération est stockée en tant que valeur de ce type (int par défaut). Il est possible de changer le type sous-jacent par défaut pour les énumérations avec la syntaxe suivante : enum <nomenum> : <typesousjacent> valeur1, valeur2, valeurx Les types sous-jacent autorisés pour les énumérations sont : byte, sbyte, short, ushort, int, uint, long et ulong. Par défaut, chaque valeur reçoit automatiquement une valeur du type sous-jacent, en partant de zéro et en augmentant de 1 à chaque nouvelle valeur. Il est cependant possible de définir explicitement les valeurs pour une ou plusieurs des constantes définies dans le corps de l'énumération avec la syntaxe suivante : 75

76 enum <nomenum> : <typesousjacent> valeur1 = valeur1, valeur2 = valeur2, valeurx = valeur Méthodes de la classe Enum La classe System.Enum définit des méthodes statiques pratiques pour effectuer différentes opérations sur les types énumérations. Citons entre autres les méthodes GetName(), GetNames, Parse(), et GetValues(). 3.3 Les espaces de noms (namespaces) Les espaces de nom (ou namespaces) nous fournissent un moyen efficace de regrouper des éléments (classes, structs, énumérations, etc..) dans des structures sémantiques. Contrairement à un fichier ou à un composant, un namespace ne reflète pas un emplacement physique mais plutôt une appartenance logique importance des espaces de nom Quand nous définissons une classe par exemple, nous pouvons (et devons) l'inclure dans un namespace. Par la suite, si nous créons une autre classe dont le but est apparenté à celui de la première, nous l'incluerons dans le même namespace, créant ainsi un "groupement" indiquant aux développeurs utilisant ces classes qu'elles sont apparentées. Voici par comment inclure une classe dans un namespace namespace MonApplication using System; public class Client // du code ici.. Dans cet exemple, la classe Client est inscrite dans le namespace MonApplication. Le placement d'un type dans un namespace confère à ce type un nom dit "qualifié" composé du nom du (ou des) namespace(s) contenant le type séparés par des points, plus le nom du type lui-même. Ici, le vrai nom de la classe Client est MonApplication.Client. Cette classification nous permet d'éviter toute collision entre (par exemple) deux classes qui posséderaient le même nom. Si celle-ci se trouvent dans deux namespaces différents, il suffira de les appeler par leurs nom qualifiés pour les différencier. Il est également possible d'imbriquer des namespaces pour segmenter logiquement une application, créant ainsi une structure sémantique hiérarchisée : namespace MaSociete 76

77 namespace MonApplication namespace LogiqueMetier class Client // code de Client.. Ici, le nom complet (ou "qualifié") de la classe Client est : MaSociete.MonApplication.LogiqueMetier.Client Nous aurions également pû définir directement la hiérarchie des namespaces comme suit pour obtenir exactement le même résultat : namespace MaSociete.MonApplication.LogiqueMetier class Client // code de Client.. NOTE : Il n'est cependant pas possible de déclarer un namespace multipart imbriqué dans un autre namespace Conventions pour namespaces et répertoires Il est d'usage de calquer autant que possible la structure des répertoires dans lesquels on stocke les différents projets et solutions sur la structure hiérarchique des namespaces. On essaiera également si l'on utilise Visual SourceSafe pour gérer notre code source, de définir dans ce logiciel une structure de projets de même structure que les namespaces que nous utilisons. Ainsi, il est beaucoup plus simple de repérer rapidement les structures logiques composant nos applications. 77

78 3.3.3 Instruction using L'instruction using, que nous avons déjà remarquée dans tous les exemples de code que nous avons abordés, sert à importer les espaces de noms dans notre code, nous évitant ainsi de devoir entrer les noms qualifiés pour chacun des objets que nous utilisons. Cette instruction a la syntaxe suivante : using nomnamespace; Nous avons remarqué par exemple que tous nos fichiers de code importaient le namespace System. La raison pour cela est que tous les types intrinsèques et les objets très communs se trouvent dans ce namespace. On pourrait se passer de l'instruction using System, mais il faudrait alors saisir les noms qualifiés pour chacune des variables que nous définissons appartenant au namespace System, ce qui serait fastidieux Liste des principaux namespaces Voici la liste des principaux namespaces du framework.net : NameSpace System System.IO System.XML System.Collections System.Data System.Diagnostics System.Drawing System.Windows.Forms System.Reflection System.Security System.Text.RegularExpressions System.Text System.Web.UI System.Web Contenu tous les objets intrinsèques entrées / sorties et fichiers XML objets Collections, Listes et structures de données Accès aux données Accès aux logs, trace, etc.. GDI+ et graphismes Interface Windows Réflexion et métadonnées. Sécurité RegExp Fonctions Texte Interfaces Web Accès Web Il existe bien sûr bien d'autres namespaces et sous-namespaces. La liste complète de ceux-ci avec leurs descriptions est disponible dans la documentation MSDN de Visual Studio à l'url : ms-help://ms.vscc.2003/ms.msdnqtr.2003feb.1033/cpref/html/cpref_start.htm 78

79 3.4 Classes et Structures Les classes et les structures sont différentes en cela que (entre autres) les structures sont des types valeurs et les classes des types références Définir des classes et des structures Structures Une structure est un élément de type valeur (qui dérive donc directement de System.ValueType) et qui stocke ses valeurs sur la pile. Les structures se comportent donc toujours comme des types valeurs. Les structures sont en général utilisées pour représenter des éléments "légers" comme par exemple un Point, un Rectangle ou encore une Couleur (ou tout autre type de données contenant peu d'informations). Voici la syntaxe pour déclarer une structure : struct Point2D membres de la structure. int x; int y; Une structure peut: - contenir un ou plusieurs constructeurs prenant des paramètres. - contenir des variables membres. - contenir des propriétés. - contenir des redéfinitions d'opérateurs. - contenir des méthodes. Une structure ne peut pas : - hériter d'une autre structure - initialiser ses variables membres lors de leur déclaration - contenir un constructeur sans paramètre - posséder de destructeurs C'est une erreur que de déclarer un constructeur sans paramètres pour une struct. Un constructeur par défaut est toujours implicitement fourni, qui initialise tous les membres de la structure à leur valeur par défaut. C'est une erreur que d'initialiser des champs d'une structure directement lors de leur déclaration. Bien que les structs soient des types valeurs, il est possible de les déclarer comme des classes : Point2D ou encore : Point2D mypoint; mypoint = new Point2D(); La différence entre les deux types de déclarations suivantes est la suivante : - lorsque l'on déclare une variable de type struct sans le mot-clé new, ses variables-membres ne sont pas initialisées et il faudra alors les initialiser avant de pouvoir s'en servir. 79

80 - lorsque l'on déclare une variable de type struct avec le mot-clé new, les variables membre de la struct sont automatiquement initialisées à leurs valeurs par défaut. Classes Les classes sont des types valeurs (héritant donc directement de System.Object) et se définissent en utilisant la syntaxe suivante : <modificateurs d'accès> class NomClasse // membres de la classe. Une classe est en fait un prototype qui va définir la "forme" et le comportement des objets qui vont être de ce type. Le mot <modificateurs d'accès> sera étudié plus en détail lorsque nous parlerons de l'héritage, mais on peut déjà dire que les modificateurs d'accès spécifient les différents possibilités d'instanciation des classes (comme public ou private par exemple) les classes peuvent : - contenir un ou plusieurs constructeurs prenant des paramètres ou pas. - contenir des variables membres. - contenir des propriétés. - contenir des indexeurs - contenir des redéfinitions d'opérateurs. - contenir des méthodes. - hériter d'une autre classe - posséder des destructeurs Différence entre une classe et un objet. Une classe est en fait le modèle conceptuel qui va définir le comportement des objets issus de cette classe. Un objet est un élément qui possèdera toutes les caractéristiques de la classe dont il est une instance. Pour prendre un parallèle, on pourrait considérer la classe comme un moule à gateaux et les objets comme les gateaux résultant de la cuisson dans ce moule. 80

81 3.5 Méthodes dans C# Déclaration de méthodes Définition (ECMA) Une méthode est un membre d'une classe qui implémente des opérations qui peuvent être exécutées par un objet ou une classe. Les méthodes ont une liste (possiblement vide) de paramètres, une valeur de retour (à moins que la valeur de retour soit void) et sont dites soit statiques soit non-statiques. Les méthodes non statiques, également appelées méthodes d'instances, sont appelées par des instances de la classes les contenant, alors que les méthodes statiques sont appelées par la classe elle-même. Les méthodes statiques doivent faire figurer le mot-clé static dans leur déclaration valeurs de retour Une méthode peut avoir une valeur de retour, auquel cas elle doit le signaler dans sa signature avec la syntaxe : <typevaleurretour> NomMéthode (...) et doit indiquer la valeur renvoyée avec la syntaxe : return valeur; Par exemple une méthode statique renvoyant un int et nommée GetCount() doit s'écrire : static int GetCount().. code return <valeur int>; Les méthodes qui ne renvoient doivent être déclarées avec le mot-clé void doivent comprendre une instruction return non suivie d'une valeur : Par exemple une méthode statique ne renvoyant rien nommée DoTheJob() doit s'écrire : static void DoTheJob().. code return; Invocation de méthodes La méthode Main et ses différentes syntaxes La méthode Main est la méthode qui est exécutée en premier lors de l'exécution d'un programme. Cette méthode est toujours statique et doit avoir comme type de retour soit int soit void. Voici les différents prototypes possibles pour la méthode Main : 81

82 static void Main() static void Main(string[] args) static int Main() static int Main(string[] args) Bien qu'il soit fréquent de spécifier explicitement le modificateur public, ceci n'est pas nécessaire et est le niveau d'accès par défaut affecté à la méthode Main. En fait, le programme fonctionnera même si Main est marqué comme private Passage d'arguments à Main Jusqu'à maintenant, dans les exemples de code étudiés, la méthode Main ne comportait jamais de paramètres. Toutefois, lorsqu'un programme est lancé, le CLR peut passer à la méthode Main tous les arguments définis sur la ligne de commande DOS (on peut également les définir dans Visual Studio). Pour que la méthode Main puisse traiter ces arguments, il faut qu'elle ait l'une des signatures suivantes : static void Main(string[] args) static int Main(string[] args) Dans ce cas, la méthode Main peut recevoir des arguments passés soit par la ligne de commande directement, soit spécifiées dans la boite de dialogue "Propriétés du Projet Propriétés de configuration Deboguage Arguments de la ligne de commande. A noter que le premier des arguments est toujours le nom de l'exécutable lui-même. 82

83 3.5.6 Passage d'arguments par valeur et par référence Mot-clé ref On peut passer les arguments par valeur ou par référence. Le mode de passage des arguments est par valeur par défaut. Si l'on souhaite passer un argument par référence à une fonction, on doit spécifier le mot-clé ref pour cet argument dans le prototype de la fonction mais également lors de l'appel de cette fonction comme démontré dans le code suivant : static void ModifyValue(ref int val) val += 1; // Appel du code.. static void Main() int test = 10; ModifyValue(ref test); // Après appel de ModifyValue, test vaudra 11. Le passage d'arguments par référence permet aux fonctions appelée de modifier des valeurs dans les fonctions appelantes. On note qu'une variable doit être explicitement initialisée avant de pouvoir être passée en tant que paramètre ref à une procédure. Mot-clé Out Le langage C# dispose également du mot-clé out qui induit le même comportement que le mot-clé ref, à la différence que la variable passée à la procédure n'a pas besoin d'être initialisée avant d'être transmise à la procédure appelante Passage de tableaux aux méthodes C# permet le passage de tableaux aux méthodes de la manière suivante : static void ModifyArray(int[] tableau) for (int i = 0; i <= tableau.length; i++) tableau[i] = i; 83

84 Mot-clé Params le mot-clé params permet le passage d'un nombre d'arguments variable à une fonction : static void ModifyValues(params int[] tableau) for (int i = 0; i <= tableau.length; i++) tableau[i] = i; Dans ce cas, le code appelant n'a pas besoin de fournir un tableau à proprement parler et la fonction cidessus peut être appelée avec la syntaxe suivante : int i, j, k; i = j = k = 10; ModifyValues(i,j,k); Le paramêtre tableau de la fonction ModifyValues contiendra alors : tableau[0] // sera égal à i tableau[1] // sera égal à j tableau[2] // sera égal à k Surcharger des méthodes. Le mécanisme appelé surcharge de méthodes permet de spécifier, dans une même classe ou structure, plusieurs méthodes portant le même nom, mais n'ayant pas la même signature. par exemple : static long addition(int val1, int val2) return (val1 + val2); static int addition(byte val1, byte val2) return (val1 + val2); Ces deux méthodes ont bien le même nom mais ni le même type de retour, ni les mêmes types de paramètres. Note : On ne peut pas définir de surcharge si : - deux méthodes diffèrent uniquement par leur type de retour. - deux méthodes diffèrent uniquement par un paramètre ref ou out. - deux méthodes diffèrent uniquement par les noms de leurs paramètres. 84

85 3.5.9 Membres statiques et Membres d'instance Il faut différencier les méthodes dites statiques et les méthodes dites d'instance. Les méthodes statiques doivent être déclarées avec le mot clé static et sont accessibles sans qu'il soit besoin de créér une instance de la classe qui les contient. Les membres statiques (ou partagés) sont partagés entre toute les instances d'une même classe, ce qui permet d'économiser de la mémoire. Pour appeler un membre statique d'une classe, il faut utiliser la syntaxe : NomClasse.NomMembreStatique et nom pas NomObjet.NomMembre car les membres statiques s'appliquent aux classes et non aux objets. Par exemple, les instructions Console.WriteLine() ou convert.tostring()sont statiques et on n'a pas besoin de créer une instance de la classe Console pour appeler la méthode WriteLine(), on peut l'appeler directement avec le nom de la classe Console (par ailleurs, dans le cas de la classe Console, on ne peut appeler que ses membres statiques car il est impossible de créér une instance de cette classe) Note: Par exemple, la méthode Main d'une application de type "Application Console" est toujours statique! En effet, si cette méthode n'était pas statique, il faudrait créér une instance de la classe contenant Main, mais cela supposerait que du code créée une instance avant de pouvoir appeler Main. 85

86 3.6 Propriétés Une propriété est un type de membre de classe particulier permettant en général l'accès à une variable membre de la classe de manière protégée Concept d'encapsulation Le concept d'encapsulation est l'un des grands concepts de la programmation orientée objet. On encapsule une variable dans une propriété, de manière à avoir tout contrôle sur les opérations faites sur cette variable par un client de la classe dans laquelle cette propriété est définie. Supposons le cas suivant : Nous voulons définir une classe Employé présentant un membre "Age" qui représentera l'âge du salarié. Nous pourrions tout-à fait définir la classe comme ceci : public class Salarié public byte Age; avec le code ci-dessus, un client disposant d'un objet Salarie pourrait tout à fait intervenir sur le membre Age en lecture et en écriture avec par exemple avec le code suivant : Salarié UnSalarié = new Salarié(); UnSalarié.Age = 500; Console.WriteLine(UnSalarié.Age); Cependant, si nous voulions restreindre la plage des âges possibles pour un objet Salarié à la tranche ans, nous ne pourrions le faire, car la variable Age est publique. Nous pourrions alors décider de passer cette variable en private, mais il nous faudrait alors écrire une méthode permettant de lire la valeur de l'âge d'un salarié et une autre permettant de définir la valeur de l'âge de ce même salarié. Ce procédé s'appelle "encapsuler" une variable. Ce cas de figure étant très courant, et afin de limiter le nombre de procédures, le langage C# permet l'écriture de propriétés. 86

87 3.6.2 Syntaxe des propriétés Une propriété est un type de membre particulier qui permet l'accès en lecture et/ou écriture à des variables encapsulées dans une classe. Voici la syntaxe que nous pourrions utiliser pour modifier la classe Salarié : public class Salarié private byte _Age; public byte Age get return _Age; set _Age = value; Dans ce code, on constate que la variable _Age est maintenant private et que l'on ne peut donc y accéder depuis l'extérieur de la classe. On fournit donc à cet effet une propriété Age permettant l'accès en lecture et écriture à cette variable. Lorsqu'un client voudra lire la valeur de la propriété Age, l'accesseur get de la propriété sera appelé, et l'accesseur set sera appelé quand un client voudra écrire la valeur de la propriété. Avec cette syntaxe, on constate que nous avons bien encapsulé l'accès à la variable _Age et que nous avons donc toute lattitude pour effectuer des traitements supplémentaires lors de l'accès à cette propriété. Par exemple, si, comme nous l'avions évoqué dans le paragraphe précédent, nous voulions limiter la plage des valeurs possibles pour la propriété Age à la tranche ans, il nous suffirait d'ajouter du code de vérification à l'accesseur set de la propriété, comme ceci : public class Salarié private byte _Age; public byte Age get return _Age; set if (_Age < 18 _Age > 65) Console.Write("Âge non correct"); else _Age = value; 87

88 3.6.3 Considérations générales Lecture / écriture Si l'on souhaitait limiter l'accès à la propriété en lecture seule, il suffirait de ne pas fournir l'accesseur set, et inversement, si l'on voulait une propriété en écriture seule, il suffirait de ne pas écrire l'accesseur get. Accès différents Il n'est pas possible de spécifier différents accès pour les accesseurs get et set d'une même propriété Indexeurs Un indexeur est un type spécifique de propriété permettant l'accès à un membre de classe avec la même syntaxe qu'un tableau. Les indexeurs sont très utilisés en C# dans le Framework et nous pouvons également définir un ou plusieurs indexeurs pour nos classes. Imaginons le cas suivant : public class TableauDeChaines private string[] _tableau = "AA","BB","CC","DD","EE"; public string this[byte index] get return _tableau[index]; set _tableau[index] = value; Ici, nous avons défini un indexeur. Un indexeur est une propriété avec la syntaxe suivante : <modificateuraccès> <TypeRetour> this[<typeparamètre> <NomParamètre>] On note que le nom d'un indexeur est toujours this et que cette propriété s'appelle dans le code client de la façon suivante : TableauDeChaines montableau = new TableauDeChaines(); montableau[0] = "ZZ"; Console.WriteLine(monTableau[0]); // Stocke "ZZ" dans _tableau // Lit "ZZ" dans _tableau. On peut définir plusieurs indexeurs dans une même classe du moment que ceux-ci respectent les règles définies pour surcharger des méthodes (voir point 3.5.8). Par exemple, on pourrait avoir l'indexeur : - public string this[byte index] qui nous permettrait de lire ou d'écrire à la position spécifiée par index dans le tableau contenu dans la classe. - public int this[string val] qui nous permettrait d'obtenir l'index de la case contenant la valeur spécifiée par le paramêtre val de l'indexeur. 88

89 3.7 Delegates et Evènements Définition d'un Delegate Définition : Un delegate est un type permettant de stocker des références à des fonctions. Les delegates sont déclarés comme des fonctions vides, à l'aide du mot-clé delegate. La déclaration d'un delegate est une signature de fonction comportant un type de retour et une liste de paramètres. Une fois défini, un delegate peut être utilisé comme type d'une variable, celle-ci pouvant alors être initialisée comme référence à une fonction ayant la même signature que le delegate. La fonction peut alors être appelée à l'aide de la variable delegate comme s'il s'agissait d'une fonction. Voici la syntaxe de déclaration d'un delegate : <accès> delegate <typeretour> NomDelegate(<paramètres>); par exemple : public delegate int processdelegate(int param1, int param2); Exemple d'utilisation d'un delegate simple Une fois un delegate défini, on peut l'utiliser pour appeler dynamiquement des fonctions comme dans l'exemple suivant : public class TestDelegate delegate double processdelegate(int p1, int p2); static double Multiplier(int p1, int p2) return p1 * p2; static double Diviser(int p1, int p2) return p1 * p2; static void Main() int i = 10; int j = 15; processdelegate process; Console.WriteLine("M pour Multiplier, D pour diviser"); string input = Console.ReadLine().ToUpper(); if (input == "M") process = new ProcessDelegate(Multiplier); else process = new ProcessDelegate(Diviser); 89

90 Console.WriteLine("Résultat :0",process(i,j); Ce code définit un delegate dont la signature est la même que les deux fonctions Diviser et Multiplier. La fonction Main déclare ensuite une variable process du type de ce delegate. Puis, selon la réponse de l'utilisateur, on affecte à process une nouvelle instance du delegate processdelegate qui pointe soit sur la fonction Multiplier soit sur la fonction Diviser. Enfin, on appelle la fonction représentée par le delegate avec la syntaxe : process(i,j); Delegates Multicast Dans l'exemple précédent, le delegate que nous avons utilise n'enveloppait qu'un seul appel de méthode. L'appel d'un delegate revient donc à appeler cette méthode. Si nous voulions appeler plusieurs fois la méthode, il nous faudrait effectuer plusieurs fois un appel explicite par l'intermédiaire du delegate. Cependant, il est possible qu'un delegate enveloppe plusieurs appels de méthodes. Un tel delegate est appelé "delegate multicast". Pour que cela ait un sens il faut que le type delegate retourne void (sinon, où iraient les valeurs de retour?). En fait, dès que le compilateur voit un delegate qui renvoie void, il suppose qu'il s'agit d'un delegate multicast. Prenons un exemple : delegate void MyDelegate(string s); class TestMultiCastDelegate static void Hello(string s) Console.WriteLine("Hello 0",s); static void GoodBye(string s) Console.WriteLine("Goodbye 0",s); static void Main() MyDelegate a,b,c,d; a = new MyDelegate(Hello); b = new MyDelegate(GoodBye); c = a + b; d = c a; a("a"); b("b"); c("c"); d("d"); Le code précédent génère la sortie suivante : Hello A GoodBye B Hello C // appel de a("a"); // appel de b("b"); // appel de c("c"); 90

91 GoodBye C GoodBye D // appel de c("c"); // appel de d("d"); On peut donc "composer" un delegate multicast de façon à ce qu'il appelle plusieurs fonctions à la suite en utilisant l'opérateur "+". On peut supprimer un delegate d'un delegate multicast en utilisant l'opérateur "-". Quand on appelle un delegate multicast, il appelle dans l'ordre tous les delegates avec lesquels il a été composé Evènements Un évènement est une notification (un message) qu'un objet envoie à un autre objet. Vous avez certainement déjà utilisé des évènements si vous avez, par exemple exécuté du code lorsqu'un utilisateur cliquait sur un bouton de votre feuille. Un évènement doit appeler des "gestionnaires d'évènements" qui sont la ou les fonctions qui seront appelées lorsque l'évènement sera déclenché. Nous allons prendre un exemple de code pour étudier le fonctionnement des évènements. Pour cela, nous allons définir une classe Generateur avec une propriété Text. Quand la valeur de cette propriété Text va changer, nous déclencherons un évènement nommé Changed. Puis, nous allons définir une classe Client qui contiendra une propriété de type Generateur nommée MyGenerateur. Lorsque nous changerons la propriété Text de cette propriété MyGenerateur, nous traiterons l'évènement Changed en affichant dans la console un message indiquant que le texte a changé. Les évènements font appel aux delegates pour fonctionner. On peut décomposer le processus pour générer et traiter un évènement en quatre étapes principales : - déclarer le delegate qui va définir la signature des gestionnaires d'évènements - déclarer l'évènement lui-même dans la classe Generateur - déclencher l'évènement lors de l'accès en écriture à la propriété Text. - souscrire à l'évènement dans la classe Client. 91

92 Etape 1: Déclarer le delegate. Pour pouvoir déclarer un évènement, il faut d'abord déclarer un type delegate, dont le prototype définit le jeu d'arguments qui vont être passés à la méthode qui va traiter l'évènement dans la classe Client (dans laquelle se trouveront les gestionnaires d'évènement). public delegate void TextChangedEventHandler(); La signature du delegate TextChangedEventHandler définit la signature des fonctions qui vont traiter l'évènement dans la classe Client. Etape 2: Définir la classe Generateur Voici maintenant le code de la classe Generateur : public class Generateur // déclaration de l'évènement. public event TextChangedEventHandler Changed; private string _Text = ""; public string Text get return _Text; set _Text = value; if(changed!= null) Changed(); Déclarer l'évènement : Voici la syntaxe utilisée pour déclarer un évènement : public event <TypeDelegate> <NomEvenement>; Ici, on déclare l'évènement Changed qui est du type Delegate TextChangedEventHandler. Déclencher l'évènement : Dans l'accesseur set de la propriété Text, on va d'abord vérifier si des clients se sont bien abonnés à l'évènement. Si c'est le cas, le delegate Changed sera différent de null (car il pointera sur la fonction destinée à traiter l'évènement). On vérifie donc si des clients ont souscrit à l'évènement avant de le déclencher (en effet si aucun code n'est "branché" pour traiter l'évènement, ce n'est pas la peine de le déclencher!) C'est tout ce dont nous avons besoin pour déclencher l'évènement dans la classe Generateur! 92

93 Etape 3: Définir la classe Client Voici le code de la classe Client : public class Client private Generateur _gen; // Constructeur de la classe Client public Client() _gen = new Generateur(); // on souscrit à l'évènement Changed.. _gen.changed += new TextChangedEventHandler(CatchEvent); // définition de la propriété MyText. public Generateur MyText get return _gen; // méthode traitant l'évènement Changed. private void CatchEvent() Console.WriteLine("L'évènement Changed s'est produit"); Ici, on déclare une variable privée de type Generateur, que l'on instancie dans le constructeur de la classe. Etape 4: Souscrire à l'évènement et le traiter Pour souscrire à l'évènement Changed, il faut indiquer quelle fonction on souhaite voir exécutée lorsque l'évènement se déclenchera. Pour cela, il faut composer un nouveau delegate pointant sur la méthode qui va traiter l'évènement (cette méthode doit bien sûr avoir la même signature que celle du delegate de l'évènement) : _gen.changed += new TextChangedEventHandler(CatchEvent); Cette ligne de code indique que lorsque l'évènement Changed va se déclencher, on va exécuter la méthode CatchEvent qui possède la même signature que le delegate TextChangedEventHandler. Depuis l'extérieur de la classe dans laquelle il est déclaré, un évènement ressemble à un champ, mais l'accès à ce champ est très limité. Les seules choses que l'on puisse faire sont soit s'abonner à l'évènement (en composant un nouveau delegate), soit se désabonner de l'évènement. Ces deux opérations sont faites avec les opérateurs += et -=. 93

94 4. Chapitre 4 : Déboguage et gestion d erreurs 1. Introduction Nous avons jusqu à présent étudié les concepts élémentaires de la programmation C#. Avant d aborder la programmation orientée objet dans une prochaine partie, nous allons nous pencher sur le débogage et la gestion d erreurs. Les erreurs de codage sont inévitables et indépendantes des compétences du développeur. La capacité de les anticiper fait d ailleurs parties des qualités d un bon développeur. Ces erreurs désignent à la fois les erreurs syntaxiques qui empêchent la compilation (on les appelle des erreurs de syntaxe), mais peuvent également survenir pendant l exécution du programme. D autres erreurs sont plus subtiles. Votre application ne parvient peut-être pas à ajouter un enregistrement dans une base de données car vous avez oublié d indiquer un champs nécessaire ou ajouté un enregistrement erroné dans d autres circonstances bien précises. De telles erreurs, qui impliquent la logique applicative, sont appelées erreurs sémantiques ou erreurs de logique. Le plus souvent, les erreurs les plus subtiles sont signalées par les utilisateurs qui se plaignent que quelque chose ne fonctionne pas correctement. Dans de telles situations, vous pourrez constater que les fonctions de débogage de VS sont vraiment d un grand secours. Dans cette première partie, nous aborderons les techniques mises à votre disposition pour régler des problèmes récurrents. En outre, nous étudierons les techniques de gestion d erreurs disponibles en C#. Ces techniques sont propres au langage C#, mais VS offre également des outils de débogage performants. 2. Déboguage dans Visual Studio.net Le mode débogage est un mode d exécution spécifique pour les applications. Les versions de débogage enregistrent des informations symboliques sur l application, de telles façons que Visual Studio.net puisse savoir exactement ce qui se passe ligne après ligne. Les informations symboliques conservent, entre autres, les noms des variables utilisées dans le code non compilé, ce qui permet d établir une correspondance avec ces dernières et les valeurs existantes dans l application compilée en code machine, qui comporte des informations incompréhensibles pour le développeur. Ces informations sont stockées dans des fichiers à l extension.pdb qui résident dans les répertoires Debug. Elles peuvent être exploitées pour effectuer, entre autres, les opérations utiles suivantes : Affichage d informations de débogage dans VS ; Examen et modification des valeurs de variables lors de l exécution de l application ; Suspension et reprise de l exécution du programme ; Arrêt automatique du programme à certains emplacements du code ; Exécution pas à pas du programme ; Contrôle des modifications du contenu d une variable pendant l exécution de l application ; Modification du contenu des variables à l exécution ; Exécution d appels de test de fonctions ; Dans cette partie, nous étudierons ces techniques et la façon de les utiliser pour identifier les zones de code qui ne fonctionnent pas comme prévu et les corriger, activités connues sous le nom de débogage. 94

95 Selon la terminologie VS, une application s exécute en mode normal ou en mode point d arrêt ; dans ce dernier cas, l exécution normale de l application est interrompue. Nous étudierons tout d abord les techniques d exécution en mode normal. 2.1 Déboguage en mode «normal» L une des fonctions que nous utilisons dans ce mode est Console.WriteLine() car elle permet d afficher du texte à la console. Lors du développement d applications, cette fonction est très pratique. Exemple : Console.WriteLine("MaFonction () est maintenant appelée"); MaFonction(); Console.WriteLine("MaFonction () a été maintenant appelée"); Une méthode efficace qui risque cependant de saturer la sortie écran. Pour éviter cela, vous pouvez diriger le texte vers un autre emplacement : la fenêtre Sortie de Visual Studio. Dans le chapitre 1, nous avons rapidement abordé la fenêtre Sortie qui, par défaut, se trouve dans la partie inférieure de l environnement de développement VS. Cette fenêtre affiche des informations relatives à la compilation et à l exécution du code, comme les erreurs de compilation, par exemple. 2.2 Afficher des informations de déboguage utiles L affichage d informations dans la fenêtre Sortie lors de l exécution de l application est simple. Il suffit de remplacer les appels de Console.WriteLine() par des appels de la fonction de débogage appropriée. Pour cela, vous pouvez utiliser deux fonctions distinctes : Debug.WriteLine(); Trace.WriteLine(); Attention : Afin de pouvoir utiliser ces fonctionnalités, il nous faut importer l'espace de nom appelé System.Diagnostics. Ces commandes jouent le même rôle à la différence que Debug.WriteLine() ne fonctionne que pour les versions de débogage alors que Trace.WriteLine() fonctionne également pour les versions de production. En fait, la commande Debug.WriteLine() ne sera pas traitée lors de la compilation de la version de production. Elle disparaîtra simplement lors de la compilation, ce qui présente certainement des avantages (comme celui d obtenir des fichiers compilés de taille inférieure). Nous pouvons en effet générer deux versions d une même application à partir d un seul fichier source. La version de débogage affiche toutes sortes d informations de diagnostic, qui, dans la version de production, sont masquées à l utilisateur. Outre les fonctions WriteLine(), vous devez connaître un certain nombre d autres fonctions d affichage. Il existe un certain nombre de fonctions équivalentes à Console.Write() : Debug.Write(); Trace.Write(). 95

96 Ces deux fonctions emploient la même syntaxe que les fonctions WriteLine() (un ou deux paramètres ainsi qu un message et une catégorie optionnelle), mais diffèrent de celle-ci car elles n ajoutent pas de caractères fin de ligne. Notez également les commandes suivantes : Debug.WriteLineIf(); Trace.WriteLineIf(); Debug.WriteIf(); Trace.WriteIf(). Chacune d elle possède les mêmes paramètres que ses homologues sans «If», avec, en plus, un paramètre obligatoire supplémentaire en tête de liste. Ce paramètre prend une valeur booléenne (ou une expression évaluant une valeur booléenne). La fonction n affiche le texte que si cette valeur est true. Ces fonctions permettent d afficher du texte sous certaines conditions dans la fenêtre Sortie. Par exemple, nous pourrions avoir besoin d afficher des informations de débogage dans certaines conditions correspondant chacune à une intrusion Debug.WriteLineIf() précise dans le code. Si la condition n est pas remplie, les informations ne s afficheraient pas à la fenêtre Sortie. 2.3 Déboguage en mode point d arrêt ou pas à pas Entrer en mode Point d arrêt Le moyen le plus simple de basculer en mode d arrêt est d appuyer sur le bouton Pause alors que l application s exécute dans VS. Ce bouton se trouve dans la barre d outils Debug qu il est recommandé d ajouter aux autres barres d outils qui s affichent par défaut dans VS. La barre d outils qui apparaît se présente ainsi : Lors de l exécution d une application, la barre d outils se présente ainsi : Les trois boutons qui étaient grisés sont à présent disponibles et permettent de : Suspendre l application pour basculer en mode point d arrêt ; Arrêter complètement l application (pour la quitter sans entrer dans le mode point d arrêt) ; Redémarrer l application. La suspension de l application est probablement le moyen le plus simple de basculer dans le mode point d arrêt, mais elle ne permet pas de choisir précisément la ligne où l arrêt va survenir. Il est préférable d utiliser des points d arrêt. 96

97 2.3.2 Définir des point d arrêt dans le code Un point d arrêt est un marqueur qui, placé dans le code source, permet de basculer automatiquement dans le mode arrêt. Il peut être configuré pour basculer dans le mode arrêt : Dès que le point d arrêt est atteint ; Si une expression booléenne est évaluée à true ; Lorsque le point d arrêt est atteint un certain nombre de fois ; Puis interrompre l exécution du programme au point d arrêt chaque fois que change la valeur de la variable qui lui est associée. Notez que les points d arrêts ne sont utilisables qu avec les programmes dans les constructions en mode débogage. Si vous compilez une version release, tous les points d arrêt seront ignorés. Pour ajouter un point d arrêt simple, il suffit de cliquer sur la zone grise à gauche de la ligne où vous souhaitez le placer. Le point d arrêt est alors symbolisé par n cercle rouge en regard de la ligne, qui est alors mise en évidence. Les informations relatives aux points d arrêt d un fichier source sont également consultables par l intermédiaire de la fenêtre Points d arrêt. Pour l activer, sélectionnez "Déboguer Fenêtre Points d arrêt". La fenêtre suivante apparaît alors dans la partie inférieure de l écran, au même endroit que les fenêtres "Liste des tâches" et "Sortie": Pour désactiver un point d arrêt, supprimez la marque dans la marge (le cercle rouge est alors vide), supprimez le point d arrêt ou éditez les propriétés de celui-ci. "Condition de point d arrêt" et "Nombre d accès à un point d arrêt" font partie des deux propriétés les plus utiles. Pour éditer un point d arrêt, il suffit de cliquer-droit dessus (dans le code ou dans cette fenêtre) et de sélectionner l option Propriétés. Trois onglets, Fonction, Fichier et Adresse, permettent alors de modifier l emplacement du point d arrêt. 97

98 Dans Adresse, nous pouvons associer une adresse mémoire absolue au point d arrêt. Les boutons Condition de point d arrêt et Nombre d accès à un point d arrêt permettent de modifier les deux propriétés indiquées précédemment. Si vous sélectionnez le bouton Condition d'un point d arrêt, la boîte de dialogue suivante apparaît : Nous pouvons alors taper une expression booléenne mettant en œuvre des variables dans la portée du point d arrêt. Si vous sélectionnez le bouton Nombre d accès à un point d arrêt, la boîte de dialogue suivante apparaît : Il est alors possible de spécifier le nombre de passages au-delà duquel le point d arrêt sera activé. La liste déroulante propose les options suivantes : toujours s arrêter s arrêter lorsque le nombre d accès est égal à.. s arrêter lorsque le nombre d accès est un multiple de. s arrêter lorsque le nombre d accès est supérieur ou égal à.. Cette option est très pratique dans les traitements longs. Il serait en effet fastidieux de devoir arrêter et redémarrer un programme fois, par exemple, avant de pouvoir afficher la valeur d une variable spécifique. 98

99 Le nombre de points d'arrêts que vous pouvez créer dans un programme n'est pas limité par Visual Studio. En général, la création de deux ou trois points d'arrêt et le parcours du code en pas à pas permet d'identifier rapidement les erreurs de logique Autres moyens d activer le mode arrêt Le mode Arrêt peut également être activé dans les deux situations suivantes : quand une exception non gérée est levée (cette notion est traitée à la partie consacrée à la gestion des erreurs, plus loin) et quand une assertion est générée. Les assertions sont des instructions qui interrompent l exécution d une application, en affichant un message personnalisé. Lors du développement, elles permettent de s assurer que le programme fonctionne comme prévu. Supposons que la valeur d une variable donnée doive être inférieure à 10. Une assertion permettrait de vérifier la condition et d afficher un message si la valeur atteint ou excède 10. Lorsqu une assertion se produit, il est possible de quitter prématurément le programme (option Abort), de basculer dans le mode Arrêt (option Retry) ou de poursuivre le traitement comme si de rien n était (option Ignore). Comme pour les fonctions de débogage étudiées précédemment, il existe deux versions de la fonction d assertion : Debug.Assert(); Trace.Assert(); La fonction Debug.Assert() n est pas prise en charge dans les applications de production. Ces fonctions acceptent trois paramètres. Le premier est une valeur booléenne qui déclenche l assertion lorsqu elle est égale à false. Le deuxième et le troisième sont des paramètres chaînes permettant d afficher des informations dans une boîte de dialogue contextuelle et dans la fenêtre Sortie. L exemple précédent nécessiterait un appel de fonction tel que celui-ci : Debug.Assert(myVar < 10, "myvar est >= 10", "Assertion atteinte dans MaFonction()" ou encore Trace.Assert(myVar < 10, "myvar est >= 10", "Assertion atteinte dans MaFonction()" Nous pourrions, par exemple, fournir une brève description de l erreur dans la première chaîne, et des instructions dans la seconde. Si l assertion se produit, l utilisateur verra la apparaître une boîte de dialogue avec les deux messages "myvar <=10" et Assertion Atteinte dans MaFonction" affichés, ainsi que les trois boutons "Abort", "Retry" et "Ignore". Si l utilisateur appuie sur le bouton Retry de Visual Studio en version release, il ne verra pas le code mais ces instructions de langage assembleur qui ne lui parleront pas beaucoup. 99

100 3. Contrôler le contenu des variables Le contrôle du contenu des variables est une exemple d opération difficile que Visual Studio simplifie. Le moyen le plus aisé de contrôler la valeur d une variable est de survoler le nom de cette dernière avec la souris dans le code. alors que nous sommes en mode point d'arrêt. Des informations relatives à la variable, telles que sa valeur, apparaissent dans une info-bulle jaune. 3.1 La fenêtre «Variables locales» Toutes les fenêtres fonctionnent plus ou moins de la même façon. Elles comportent différentes fonctionnalités supplémentaires selon le contexte. En général, chaque fenêtre comporte une liste de variables avec des informations relatives à leur nom, leur valeur et leur type. Les symboles + et associés aux variables plus complexes, comme les tableaux, permettent de développer ou de masquer leur contenu dans l arborescence. Cette vue permet également de modifier le contenu des variables, ce qui est pratique si l affectation de valeurs n a pas lieu dans le code. Il suffit pour cela de taper une nouvelle valeur dans la colonne Valeur de la variable à éditer. Cette technique est très pratique pour tester des scénarios de modifications de valeurs, par exemple. 3.2 La fenêtre «Recherche» D un nombre maximal de quatre, la fenêtre Recherche permet de contrôler des variables ou expressions spécifiques impliquant des variables spécifiques. Pour utiliser une fenêtre Recherche, il suffit de taper le nom de la variable ou de l expression dans la colonne Nom et d observer les résultats. Notez que toutes les variables d une application ne sont pas visibles simultanément, et sont signalées comme telles dans la fenêtre Résultats de la recherche. 100

101 Pour ajouter des variables dans une fenêtre Recherche, il suffit de les faire glisser à partir du code source. Pour ajouter d autres fenêtres, nous pouvons utiliser les options Déboguer Fenêtre Recherche Résultats de la recherche permettant d activer et de désactiver les quatre fenêtres autorisées. Chaque fenêtre peut contenir un jeu particulier d inspecteurs sur les variables et les expressions, ce qui facilite le regroupement de variables associées et leur accès. A l instar des fenêtres Résultats de la recherche, la fenêtre QuickWatch permet d accéder rapidement à des informations détaillées relatives à une variable directement dans le code source. Pour cela, il suffit de cliquer droit sur la variable à interroger et de sélectionner l option QuickWatch. Le plus souvent, les fenêtres Résultats de la recherche standard permettent d effectuer les mêmes opérations. Il est important de noter que les inspecteurs sont conservés d une exécution d application à l autre. Visual Studio mémorise ces points d arrêt entre les sessions. 3.3 Différents mode de pas à pas Nous avons vu comment examiner ce qui se passe au point exact où VS bascule en mode Arrêt. Nous allons à présent découvrir comment exécuter les instructions pas à pas. Les commandes de pas-à-pas sont disponible via la barre d'outils Debug, le menu Debug, ou encore les raccourcis clavier. Voici les trois mode de pas-à-pas en C# Pas-à-pas détaillé (F11) : exécute l'instruction en cours et passe à la suivante Pas-à-pas principal (F10): même opération que ci-dessus mais les blocs imbriqués ne sont pas détaillés. Pas à pas sortant (Shift+F11): exécute le bloc de code en cours jusqu'à la fin et repasse en mode Arrêt. L'utilisation de et le parcours du code avec ces différents modes de pas-à-pas est particulièrement bien adaptée à la détection d erreurs sémantiques. Elle permet d aller directement à l emplacement suspect et de vérifier si les erreurs se produisent. 3.4 La fenêtre «Command» La fenêtre Fenêtre Commande possède deux modes. Le mode Commande permet d effectuer des opérations dans VS sans passer par la barre de menus. Le mode Immédiat permet d exécuter du code entre des instructions standard et d évaluer des expressions. En mode Commande, chaque ligne commence par le signe supérieur à (>). Pour basculer en mode immédiat, il suffit de taper immed dans cette fenêtre et d appuyer sur Entrée, puis de taper >cmd et d appuyer sur Entrée pour revenir dans le mode précédent. Nous nous concentrerons sur le mode Immédiat, car le mode Commande n est utile que pour les opérations complexes. L utilisation la plus simple de cette fenêtre consiste à évaluer des expressions, de façon «instantanée» comme dans les fenêtres Rechercher. Pour cela, il suffit de taper une expression et d appuyer sur Entrée. Les informations demandées s affichent alors. Par exemple : NomVariable (NomVariable1 * NomVariable2) Nous pouvons également modifier le contenu des variables. Exemple : NomVariable =

102 3.5 La fenêtre «Pile des appels» Il s agit de la dernière fenêtre que nous étudierons ici. Elle indique le nom de la fonction en cours d exécution, la fonction d appel ainsi que les imbrications d appels de fonctions. Le point d appel est également enregistré. Cette fenêtre est particulièrement utile lorsque des erreurs sont détectées en premier, car elle permet de voir ce qui s est produit immédiatement avant et ce qui a causé l erreur. Cette fenêtre affiche parfois des informations difficiles à comprendre. Il arrive que des erreurs se produisent hors des applications, dans des fonctions externes. Dans ce cas, la liste d informations concerne ces fonctions et la pile des appels comprend des entrées vers des fonctions compilées. A noter que l'objet Exception possède une propriété StackTrace qui permet également de consulter la pile des appels sans disposer de Visual Studio.net. 102

103 4. Gestion des Erreurs 4.1 Les exceptions Une exception est une erreur générée lors de l exécution du code ou lors de l exécution d une fonction. Nous avons déjà abordé les exceptions dans ce cour. Un moyen simple d'en générer une est de lire un élément de tableau hors des bornes de celui-ci. Exemple : int[] myarray = 1, 2, 3, 4; int item = myarray[10]; Ceci génère le message d exception suivant et met fin à l application : An unhandled exception of type «System.IndexOutOfRangeException» occured in <nomfichier> <nomfichier> est le nom du fichier comportant l exception. Les exceptions sont définies dans des espaces de noms. Elles portent généralement un nom correspondant à leur rôle et à l erreur traitée. Dans notre exemple, l exception générée s appelle System.IndexOutOfRangeException, nom qui signifie que l indice spécifié se trouve en dehors de l intervalle autorisé dans myarray. Ce message n apparaît et l application ne prend fin que si l exception n est pas gérée. Que signifie exactement «gérer» une exception? 4.2 La structure «try..catch..finally» Le langage C# comporte une syntaxe pour la gestion structurée de exceptions. Les mots-clés permettent de signaler le bloc d instructions à exécuter lorsqu une exception survient. Il s agit de try, catch et finally. Chaque mot-clé désigne un bloc de code particulier dont les instructions doivent nécessairement s exécuter séquentiellement. La structure de base est la suivante : try // Code pouvant générer une exception catch (<typeexception> e) // Gestion de l'exception finally // Code toujours exécuté que l'exception se soit produite ou pas. Il est également possible d insérer un bloc try et un bloc finally (sans bloc catch) ou un bloc try et plusieurs blocs catch. Si un ou plusieurs catch figure(nt) dans le programme, le bloc finally est facultatif. Autrement, il est obligatoire. 103

104 Les blocs sont utilisés comme suit : try : contient le code susceptible de lever des exceptions, ce verbe signifiant «générer» ou «causer» en termes d exceptions ; catch : contient le code à exécuter lorsque des exceptions sont levées. Les blocs catch répondent à des types d exceptions spécifiques (comme System.IndexOutOfRangeException) à l aide de <exceptiontype>, ce qui permet de définir plusieurs blocs catch dans une même application. Il est possible d omettre ce paramètre pour définir un bloc catch générique destiné à traiter toutes les exceptions ; finally : contient du code qui doit toujours s exécuter, soit après le bloc try si aucune exception ne survient, après un bloc catch si une exception est gérée, soit simplement avant qu une exception non gérée mette fin à l application (le fait que ce bloc soit traité à ce moment précis est la raison de son existence ; autrement, nous pourrions placer le code après le bloc). La séquence d évènements après le déclenchement d une exception dans un bloc se déroule ainsi : le bloc try se termine à l emplacement où est survenue l exception ; si un bloc catch existe, le programme vérifie si le bloc correspond au type d exécution levée. Dans le cas contraire, le bloc finally s exécute (il doit être défini en l absence de blocs catch) ; s il n existe pas de correspondance alors qu un bloc catch existe, un contrôle s effectue sur les autres blocs catch ; si un bloc catch correspond au type d exception, le code qu il contient s exécute, et le code du bloc finally s exécute ensuite ; si aucun bloc catch ne correspond au type d exception, le bloc finally s exécute directement. Mettre en œuvre une gestion d erreurs centralisée Il est intéressant de noter que les exceptions non gérées remontent la pile des appels jusqu'à ce qu'elles trouvent un bloc catch permettant de les traiter. On appelle ce comportement le "bubbling" (pour bubbles qui veut dire "bulles") car les exceptions remontent la pile des appels comme des bulles remontent à la surface de l'eau. Il est donc tout-à-fait possible de gérer les exceptions aun niveau que l'on souhaite et même mettre en œuvre une gestion d'erreurs centralisée à un point précis de l'application. 104

105 4.3 Lister et configurer des exceptions.net Framework comporte un ensemble de types d exceptions que vous pouvez lever et gérer dans un même programme ou lever dans un programme et gérer dans un autre, plus complexe. VS propose une boîte de dialogue pour examiner et éditer les exceptions disponibles. 4.5 La Fenêtre Exceptions Dans cette fenêtre, les exceptions sont classées par catégorie et par espace de noms de bibliothèque.net. Pour afficher leur liste disponible dans l espace de noms System, développez la branche de l'arbre Common Language Runtime Exceptions, puis la branche System. Chaque exception peut être configurée à l aide des boutons radio situés dans la partie inférieure de la boîte de dialogue. La plupart sont réglés par défaut sur "Useparent setting", ce qui signifie qu elles utilisent les options de niveau catégorie (toutes visibles dans l illustration précédente). Nous pouvons utiliser la première option, Lorsque l exception est levée, pour créer une rupture dans le débogueur, y compris pour les exceptions gérées. La seconde option permet de ne pas tenir compte des exceptions non gérées, avec toutes les conséquences qui en découlent. 105

106 Chapitre 5 - Concepts Orientés Objet 5.1 Constructeurs Chaque classe possède ce qui s'appelle un constructeur. Un constructeur est appelé lors de la création d'une instance de la classe à l'aide du mot-clé new. Par exemple, lorsque nous écrivons le code suivant : object o = new object(); Le constructeur de la classe System.Object est appelé Par défaut Si une classe n'implémente pas explicitement un constructeur, le constructeur dit par défaut est appelé (en fait, le constructeur de la classe object est appelé). Par exemple, on peut tout à fait définir une classe : public class Test public string Valeur = ""; et instancier cette classe avec : Test MyTest = new Test(); Il est également possible de définir explicitement un constructeur sans paramètres comme ceci : public class Test public string Valeur = ""; public Test() Valeur = "Une Valeur"; et de l'instancier de la même façon, auquel cas le constructeur Test() sera exécuté Paramétrés On peut tout à fait définir plusieurs constructeurs (surcharge) ou ne définir qu'un constructeur avec des paramètres (auquel cas, la classe ne pourra plus être instanciée en utilisant son constructeur par défaut). Un constructeur paramétré sera donc une fonction publique même nom que la classe avec des paramètres Statiques Les constructeurs statiques sont une nouveauté de C#. Ils permettent d'initialiser les variables statiques contenues dans la classe. En effet, les variables statiques peuvent être initialisées lors de leur déclaration (comme la variable j dans cette exemple), mais peuvent également être initialisées par un constructeur statique. 106

107 Notons que les constructeurs statiques sont exécutés au premier appel d'un membre statique de la classe. public class TestStaticConstructor public static int i; public static int j = 20; static TestStaticConstructor() i = 10; Appeler d'autres constructeurs depuis un constructeur. Il est possible d'appeler d'autres constructeurs depuis un constructeur. Pour cela, on dispose de la syntaxe suivante : public class BaseClass public string Nom, Prenom; public BaseClass () Nom = "NomVide"; Prenom = "PrenomVide"; public BaseClass (string nom) : this () Nom = nom; public BaseClass (string nom, string prenom) : this (nom) Prenom = prenom; Iorsque nous instancions la classe avec la syntaxe suivante : BaseClass x = new BaseClass ("aa","bb"); Les trois constructeurs sont appelés dans cet ordre : BaseClass() BaseClass(string nom) BaseClass(string nom, string prenom) Appeler des constructeurs de la classe de base Il est également possible d'appeler des constructeurs de la classe de base dans une hiérarchie d'héritage en utilisant le mot-clé base à la place du mot-clé this. public class BaseClass public string Nom, Prenom; 107

108 public BaseClass() Nom = "NomVide"; Prenom = "PrenomVide"; public BaseClass(string nom) : this () Nom = nom; public BaseClass(string nom, string prenom) : this (nom) Prenom = prenom; public class DerivedClass : BaseClass public int Age; public DerivedClass(string nom, string prenom, int age) : base (nom, prenom) Age = age; Dans ce cas, si nous instancions DerivedClass de cette manière : DerivedClass x = new DerivedClass("aa","bb",10); Les constructeurs sont appelés dans cet ordre : BaseClass() BaseClass(string nom) BaseClass(string nom, string prenom) DerivedClass(string nom, string prenom, int age) Il est important de noter que les constructeurs ne sont pas hérités. Dans l'exemple de code précédent, il ne sera donc pas possible d'instancier la classe DerivedClass avec un constructeur sans paramètres. 108

109 5.2 Destructeurs Un destructeur est une méthode d'une classe qui sera appelée quand la les objets du type de cette classe seront détruits en mémoire (d'où le nom destructeurs). Les destructeurs sont couramment utilisés en C++, mais en C#, leur utilisation est moins fréquente à cause de la façon dont le Framework.net gère les ressources en mémoire Syntaxe Pour implémenter un destructeur, il suffit de créer une méthode de nommée ~NomClasse() comme ceci : public class Test ~Test() Console.WriteLine("Destructeur Appelé"); Cependant, le Framework.net ne garantit pas le moment exact auquel sera appelé le destructeur d'une classe. Ne placez donc pas de code dans un destructeur si ce code doit s'exécuter à un moment précis! Notion de Garbage Collector et Finalisation non-déterministe COM utilisait le comptage de références pour détruire les objets en mémoire, c'est-à-dire que dès lors qu'un objet n'était plus référencé par aucun autre, il était détruit. Le Framework.net ne fonctionne pas de cette manière. Le Framework.net fournit un GarbageCollector ou "ramasse-miettes". Le GarbageCollector est un objet qui va périodiquement vérifier tous les objets qui ne sont plus référencés et les détruire. Cependant, il n'est pas possible de prédire quand le GarbageCollector va se déclencher et il n'est donc pas possible de prédire exactement quand les objets vont être détruits. On appelle cela la finalisation non-déterministe. Note : on peut cependant explicitement ordonner au Garbage Collector de détruire les objets qui doivent l'être et d'ainsi récupérer la mémoire qui leur était allouée en utilisant la méthode Collect() comme ceci : GC.Collect(); Cette opération est cependant assez coûteuse en temps et en ressources et il n'est pas conseillé d'en faire un usage fréquent. 109

110 5.2.3 Interface IDisposable et Méthode Dispose. On utilisera donc plutôt la pattern "Dispose" et l'interface IDIsposable pour nettoyer nos objets. L'interface IDisposable fournit une méthode Dipose que nous devrons implémenter pour effectuer le nettoyage des objets non managés éventuellement présents dans nos classes. Il est conseillé de préférer la pattern Dispose et l'interface IDisposable à l'implémentation de destructeurs pour nettoyer les objets. Regardons la façon d'implémenter l'interface IDisposable dans une classe : public class Test : IDisposable public void Dispose() Dispose(true); GC.SuppressFinalize(this); protected virtual void Dispose(bool disposing) if (disposing) // Nettoyage des objets managés // Nettoyage des objets non-managés ~Test() Dispose(false); La version surchargée de Dispose qui prend un paramètre booléen est la méthode qui effectue réellement le nettoyage des objets. Dispose(bool) est appelée à la fois par le destructeur et par la méthode IDisposable.Dispose() afin de s'assurer que le nettoyage ne s'effectue que dans un seul endroit. Le paramètre de Dispose(bool) indique si cette méthode a été invoquée par le destructeur ou par Dispose(). Aucun appel à Dispose(bool) ne doit figurer par ailleurs dans votre code. Le principe est le suivant : - Si du code client appelle IDisposable.Dispose(), ce client indique que toutes les ressources de l'objet (managées et non managées) doivent être nettoyées - Si un destructeur est invoqué, toutes les ressources doivent, en principe, être nettoyées. Cependant, dans ce cas, le destructeur aura été appelé par le GarbageCollector. Il reste donc à effectuer explicitement le nettoyage des ressources non-managées. Il existe une autre raison de ne pas se référer à des objets managés depuis le code invoqué dans le destructeur qui est que, comme il n'est pas possible de prédire dans quel ordre les objets sont détruits, les objets managés concernés pourraient très bien déjà avoir été détruits. Examinons le code précédent : ce qui se passe en dernier dans la méthode Dispose() est un appel à GC.SuppressFinalize(this). La méthode SuppressFinalize indique au GarbageCollector que le destructeur d'une classe n'a plus besoin d'être appelé, ce qui rend le processus de nettoyage de la mémoire plus efficace (car il se produit en une seule passe au lieu de deux). Comme Dispose() aura déjà effectué le nettoyage nécessaire, le destructeur n'aura plus rien à faire. 110

111 En procédant ainsi, vous avez une sécurité accrue pour le nettoyage de vos objets. Si le code client se souvient d'appeler Dispose(), les ressources sont nettoyées en temps voulu. Si par contre le code client oublie d'appeler Dispose(), le destructeur est appelé quand l'objet est nettoyé. 5.6 Héritage L'héritage est l'un des concepts clé de la programmation objet. En C#, et plus généralement dans tous les langages du Framework.Net, seul l'héritage simple est supporté (c'est-à-dire qu'une classe ne peut hériter que d'une seule classe directement) Héritage de classes Le concept d'héritage permet à une classe B d'hériter de toutes les fonctionnalités définies dans une classe A. Voici la syntaxe permettant à la classe ClassB d'hériter des membres de la classe ClassA. public class ClassB : ClassA le mot-clé this Le mot-clé this permet de se référer à l'instance en cours de la classe depuis l'intérieur de la classe. Par exemple, si une méthode d'une classe A doit passer à une méthode d'une classe B une référence vers l'instance en cours, il peut le faire en utilisant le mot-clé this avec la syntaxe suivante : public class ClassA public void PasserInstance() ClassB.Test(this); public class ClassB static public void Test(ClassA uneinstance) // Code utilisant l'instance passée Attention : C'est une erreur que d'utiliser le mot-clé this depuis le code d'un membre statique le mot-clé base Le mot-clé base est utilisé dans le code d'une classe dérivée pour se référer aux membres de sa classe de base. public class ClassBase public string GetInfos() 111

112 return "Une Chaîne"; public class ClassDerived : ClassBase public string Test() return base.getinfos(); Dans la classe ClassDerived, la méthode publique Test effectue un appel à sa classe de base ClassBase et appelle sa méthode GetInfos(). NOTE: Notez que le mot-clé base est également utilisé dans la déclaration des constructeurs de classes pour faire appel à un constructeur d'une classe de base. 112

113 5.6.4 Redéfinition de méthodes Le mot clé virtual est utilisé pour modifier la déclaration d'un méthode ou d'une propriété, auquel cas la méthode ou propriété est appelé membre virtuel. L'implémentation d'un membre virtuel peut être changée par un membre de même nom marqué avec le modificateur override dans une classe dérivée. Quand une méthode virtuelle est invoquée, le type réel (pas son type de déclaration) de l'objet est parcouru pour voir s'il contient un membre marqué comme override, redéfinissant la méthode. Le membre redéfini dans la classe la plus dérivée est alors appelé (ce membre peut être le membre original si aucune classe dérivée n'a redéfini le membre). Par défaut, les membres ne sont pas virtuels et l'on ne peut redéfinir un membre non-virtuel. On ne peut redéfinir un membre de classe marque comme static, abstract ou override. public class ClassBase public virtual string Test() return "ClassBase : Test"; public class ClassDerived : ClassBase public override string Test() return "ClassDerived : Test()"; public class Start static void Main() ClassBase A = new ClassBase(); ClassBase B = new ClassDerived() Console.WriteLine(A.Test()); Console.WriteLine(B.Test()); Ce code donne la sortie suivante : ClassBase : Test() ClassDerived : Test() Alors que les deux types de déclaration de A et B sont bien de type ClassBase. Ceci illustre ce que nous disions au début de cette section, à savoir que c'est bien l'implémentation de la méthode contenue dans le type réel (le "run-time type") qui est exécutée et non celle contenue dans son type de déclaration. 113

114 5.6.4 Masquage de méthodes De même que nous pouvons (avec le modificateur override) redéfinir une méthode d'une classe de base, nous pouvons également "masquer" l'implémentation d'une méthode dans une classe de base par une nouvelle implémentation dans une classe dérivée. Le masquage de noms au travers de l'héritage se produit lorsqu'une classe redéclare un nom dont il a hérité d'une classe de base. Ceci se fait avec le mot-clé new comme démontré dans l'exemple suivant : class Base public void F() class Derived: Base public new string F() return ""; Le but du mot-clé new est d'indiquer qu'il s'agit bien d'une nouvelle implémentation de la méthode F() (qui d'ailleurs, ne prend pas les mêmes paramètres). 5.7 Interfaces Une interface est un contrat! Une classe ou structure implémentant une interface doit adhérer à ce contrat, c'est-à-dire fournir une implémentation pour tous les membres définis dans le corps de l'interface. Une Interface peut hériter d'autres interfaces, et une même classe peut implémenter plusieurs interfaces. Les interfaces peuvent contenir des méthodes, des propriétés, des évènements et des indexeurs. L'interface elle-même ne fournit jamais d'implementation pour les membres qu'elle contient mais simplement définit les membres que devront fournir (et donc implémenter) les classes et/ou structures qui implémenteront cette interface. Voici la syntaxe pour déclarer une interface : interface IControl void Paint(); Cette interface définit un membre Paint() ce qui implique que toutes les classes et structures implémentant cette interface devront fournir ce membre. 114

115 5.7.2 Implémentation d'interfaces Quand une classe implémente une interface, elle doit le signaler dans sa déclaration comme ceci: public class Lion : ICarnivore Si la classe hérite d'une autre classe, il nous faut d'abord indiquer le nom de la classe de base, puis le non de la ou des interfaces que la classe implémente : public class Lion : Animal, ICarnivore, IPredateur Regardons l'exemple d'une classe imaginaire TextBox implémentant l'interface IControl. interface IControl void Paint(); class TextBox: IControl public void Paint() // Code de la méthode Polymorphisme par les interfaces Les interfaces sont un autre moyen d'implémenter le polymorphisme. Alors que l'héritage représente une relation que nous pourrions énoncer comme "est un", les interfaces définissent une relation que nous pourrions appeler "peut se comporter en tant que". Exemple : Par exemple supposons que nous ayons défini une classe Lion, une classe Aigle et une classe Crocodile et que toutes ces classes héritent de la classe Animal. Nous pourrions tout à fait créer un tableau de type Animals et stocker dedans des références vers des objets Lion, Aigle ou Crocodile (si le type de déclaration de ceux-ci est bien Animal). C'est le polymorphisme de classe que nous avons évoque plus haut. Mais, nous constatons que ces trois classes ont des choses en commun : ce sont tous des carnivores. Nous pourrions inclure les méthodes communes à tous les carnivores dans la classe Animal mais, dans ce cas, nous ne pourrions plus faire hériter la classe Lapin de la classe Animal. Comme le langage C# ne supporte que l'héritage simple (une classe ne peut hériter que d'une seule autre classe), la solution se trouve dans les interfaces. En effet, nous constatons que les trois classes évoquées ci-dessus implémentent bien la relation d'héritage "est un" (un Lion est un Animal, un Aigle est un Animal, etc..). Mais l'usage des interface nous permet d'implémenter la relation "peut se comporter en tant que" (un Lion peut se comporter en tant que carnivore, un Aigle aussi, etc..). C'est ce que nous démontre l'exemple de code suivant : 115

116 public class Animal private short _Poids; public short Poids get return _Poids; set _Poids = value; interface ICarnivore string Chasser(); public class Lion : Animal, ICarnivore public void Rugir() Console.WriteLine("Le Lion 0 rugit."); public string Chasser() Console.WriteLine("Le lion chasse des biches"); public class Aigle : Animal, ICarnivore public void Voler() Console.WriteLine("L' Aigle 0 vole."); public string Chasser() Console.WriteLine("L' Aigle chasse des souris"); Nous voyons que Aigle et Lion dérivent tous deux d'animal mais implémentent aussi l'interface ICarnivore. On peut donc les traiter comme des ICarnivore. static void Main(string[] args) Lion UnLion = new Lion(); Aigle UnAigle = new Aigle(); ICarnivore[] Chasseurs = UnLion, UnAigle; foreach (ICarnivore c in Chasseurs) c.chasser(); Cette façon d'implémenter le polymorphisme avec les interfaces est extrêmement pratique et permet de pallier les limitations du polymorphisme d'héritage. 116

117 5.7.3 Héritage d'interfaces Une interface peut tout-à-fait hériter d'une autre interface. Dans l'exemple de code suivant, l'interface ITextBox hérite de l'interface IControl. Toute classe implémentant l'interface ITextBox devra donc fournir une implémentation des membres de ITextBox et des membres de IControl. interface IControl void Paint(); interface ITextBox: IControl void SetText(string text); class TextBox: ITextBox public void Paint()... public void SetText(string text)... Le polymorphisme d'interfaces que nous avons étudié dans la section précédente s'applique fort bien aux hiérarchies d'héritage d'interfaces. Ici, nous pourrions tout à fait stocker des objets de type TextBox dans un tableau de type IControl ou dans un tableau de type ITextBox. 117

118 5.7 Classes Classes abstraites Le mot-clé abstract est utilisé pour indiquer qu'une classe est incomplète et qu'elle ne doit être utilisée qu'en tant que classe de base. Un classe abstraite diffère d'une classe non-abstraite par les comportements suivants : - Une classe abstraite ne peut pas être instanciée directement. On peut cependant déclarer des variables de types de classes abstraites dès lors que l'on leur affectera soit null soit une référence vers une classe non abstraite dérivant de la classe abstraite. - Une classe abstraite peut contenir des membres abstraits. - Une classe abstraite ne peut pas être déclarée avec le modificateur sealed. Lorsqu'une classe non-abstraite est dérivée d'une classe abstraite, la classe non abstraite doit fournir une implémentation pour tous les membres abstraits de la classe de base, en redéfinissant ces membres abstraits. On peut considérer les classes abstraites comme un concept à mi-chemin entre les classes de base non abstraites et les interfaces en ce sens que l'on peut hériter d'elles mais qu'elles définissent également un contrat en cela que les classes dérivant d'une classe abstraite doit fournir une implémentation pour tous les membres abstraits définis dans la classe abstraite. Regardons l'exemple de code suivant : abstract class A public abstract void F(); abstract class B: A public void G() class C: B public override void F() // actual implementation of F La classe abstraite A déclare une méthode abstraite F(). La classe B fournit une autre méthode G(), mais, comme elle ne fournit pas d'implémentation pour sa classe de base, elle doit également être abstraite. La classe C redéfinit (override) la méthode F() et fournit son implémentation. Comme la classe C ne déclare pas de membres abstraits, on peut déclarer la classe C comme non abstraite. 118

119 5.7.2 Classes sealed Si l'on souhaite empêcher que l'on puisse hériter d'une classe, on peut déclarer celle-ci avec le mo-clé sealed. Une erreur de compilation se produit si vous essayez d'instancier une classe déclarée comme sealed. Ce motclé est l'équivalent du mot-clé final en Java. Une classe sealed ne peut pas être déclarée abstract. Déclarer une classe comme sealed peut être intéressant pour de nombreuses raisons, l'une d'entre elles étant la possibilité pour un développeur fournissant un composant d'empêcher les clients ayant acheté son composant de dériver leur propres classes des classes du composant Niveau d'accessibilité des classes et des membres. Les classes peuvent être déclarées avec différents modificateurs d'accès qui définiront leurs possibilités d'accès et d'instanciation depuis du code client et depuis d'autres assemblys. les différents niveaux d'accessibilité pour les classes sont définis par les modificateurs d'accès suivants : publique (mot-clé public) qui indique que la classe est publique privée (mot-clé private) qui indique que la classe est privée (ce niveau est seulement disponible pour les classe imbriqueés dans d'autres classes). interne (mot-clé internal) indique que l'accès à la classe est restreint aux éléments contenus dans le même assembly. La valeur par défaut pour les classes est internal. Les modificateurs d'accès possibles pour un membre peuvent être l'un des suivants : Public (mot-clé public) qui définit un accès non limité au membre Protégé (mot-clé protected) qui indique que le membre est accessible dans la classe qui le contient et aux classes dérivées de cette classe Interne (mot-clé internal) qui indique que l'accès au membre est limité aux élements contenus dans le même assembly. Interne protégé (mots-clé protected internal) qui indique que l'accès est autorisé seulement aux éléments contenus dans le même assembly ou aux membres dérivant de la classe contenant le membre interne protégé. Privé (mot-clé private) qui indique que l'accès au membre est limité au type qui le contient. 119

120 En fonction du contexte dans lequel est situé une déclaration de membre, seuls certains types de modificateurs d'accès sont permis. De plus, quand la déclaration d'un membre n'inclut pas de modificateurs d'accès, l'accès à ce membre est défini par défaut, comme dans la liste suivante : Les namespace sont toujours public par défaut. Aucun modificateur d'accès n'est autorisés pour une déclaration de namespace Les types déclarés directement dans des namespaces peuvent seulement être public ou internal. Les membres de classes peuvent avoir l'un des cinq modificateurs d'accès définis plus haut dans cette section. Les membres des structures (struct) peuvent avoir les accessibilités suivantes : public, private ou internal. Les membres d'interfaces sont toujours implicitement public. Il n'est cependant pas permis d'inclure le modificateur public pour ces membres. Les membres des énumérations sont toujours implicitement public. Il n'est cependant pas permis d'inclure le modificateur public pour ces membres. 120

121 Annexe 1 Conventions de codage en C#. 1. Introduction Nous examinerons ici les recommandations écrites de Microsoft en ce qui concerne les conventions de codage en langage C#. Tout langage de développement possède généralement un style de programmation qui lui est propre. Ce style ne fait pas partie du langage lui-même mais représente un ensemble de conventions concernant le langage. Ces conventions incluent par exemple des règles de nommage des variables, la casse à utiliser selon les cas, et les modes d'utilisation des classes, méthodes et fonctions. Si la majorité des développeurs suivent les mêmes conventions, la lecture et la maintenance du code est facilitée pour tout le monde et il sera ainsi plus facile pour un développeur de comprendre le code écrit par un autre. Ces conventions sont consultables dans l'aide MSDN aux adresses suivantes : Pour les conventions générales de conception : ms-help://ms.netframeworksdkv1.1/cpgenref/html/cpconnetframeworkdesignguidelines.htm Pour les conventions de nommage des éléments : ms-help://ms.netframeworksdkv1.1/cpgenref/html/cpconnamingguidelines.htm Bien sûr, l'ensemble de toutes les recommandations de codage pour adopter de bonnes pratiques de programmation représente une quantité importante d'informations à "digérer". Dans le cadre de cette annexe, nous ne ferons que reprendre les points les plus importants de ces recommandations. Si vous voulez être certains que votre code suit à la lettre les recommandations de codage en vigueur, il vous est conseillé de vous reporter à la documentation MSDN. 2. Conventions de nommage Les conventions de nommage ont toujours fait l'objet de discussion passionnées entre les développeurs et architectes d'application, chacun débattant longuement des avantages et inconvénients de leurs propres méthodes. Ainsi, dans Visual Basic 6, les développeurs utilisaient une convention qui consistait à préfixer les noms de variables par une abréviation représentant le type de la variable déclarée. Par exemple, une variable de type string nommée "Nom" se serait écrite : Dim strnom as string. Les conventions dépendent cependant également des langages et plateformes utilisées. Par exemple, les développeurs C++ qui programment sur des plateformes Windows utilisent des préfixes psz ou lpsz pour indiquer des chaînes de caractères (ex: char *pszresult; ou encore char *lpszmessage;) Mais, sur des machines Unix, il n'es pas rare de voir des développeurs n'utilisant pas ces mêmes préfixes (ex: char *Result; ou encore char *Message;). 121

122 La convention selon laquelle les noms de variables sont précédés de lettres représentant le type de données est connue sous le nom de notation hongroise. Il est ainsi possible, pour un développeur, de reconnaître immédiatement le type de la variable à la lecture de son nom. En ce qui concerne les conventions de codage en C#, nous n'utiliserons pas la notation hongroise. En effet, dans le Framework.NET, tout est objet. On ne peut donc pas préfixer les noms de variables avec un préfixe indiquant le type de données (ou alors, on ne préfixerait que les variables représentant les types de données intrinsèques). Intuitivement on peut dire que les noms devraient refléter la destination de l'élément et n'entrer en conflit avec aucun autre nom. Dans le Framework.Net, la philosophie générale de la dénomination des variables suggère que le nom de la variable devrait refléter l'emploi de l'instance de cette variable et non son type de données (par exemple Longueur est un bon nom de variable alors que ValeurEntière ne l'est pas). 3. Casse des noms d'éléments (Pascal Casing et Camel Casing) Pour résumer, on emploie deux types de casse de caractères appelés : Pascal Casing (Une majuscule au début de chacun des mots composant le nom d'élément). Camel Casing (on commence le nom en minuscules, puis, une majuscule au début de chaque mot. Exemple de Pascal Casing : WindowHeight, WriteLine Exemple de Camel Casing : windowposition, integralheight Il est déconseillé d'utiliser la syntaxe consistant à séparer les mots par un caractère "underscore" comme dans ("Window_Position") De même, il est déconseillé d'écrire les noms de constantes en majuscules, comme c'était le cas dans certains langages précédents (comme dans Visual Basic 4,5 et 6 par exemple). On peut également prendre en compte la portée des éléments pour savoir quelle casse (Pascal ou Camel) utiliser pour nommer un élément. En général, tous les éléments publics sont écrits en Pascal Casing alors que les éléments privés seront plutôt écrits en Camel Casing. Par exemple : les noms de tous les paramètres passés à une méthode devraient être en casse Camel : public void RecordSale(string salesname, int quantity) vous devriez utliser la casse Camel pour établir une distinction entre deux éléments qui, autrement auraient exactement le même nom. Un exemple commun est celui d'une propriété encapsule un champ : private string nomsalarie; public string NomSalarie get 122

123 set return nomsalarie; nomsalarie = value; Pour ce qui est des conventions, le code précédent est acceptable. Il est important de rester attentif à la casse des éléments que vous définissez, et, dans tous les cas de figure, d'adopter une règle pour la casse et de s'y tenir. Il est pratique par exemple de savoir immédiatement que la variable nomsalarie est une variable privée, juste en analysant sa casse. En tout état de cause, le langage C# est sensible à la casse et il est donc important de porter une attention particulière aux conventions de nommage des éléments. 4. Style des Noms d'éléments. Essayez d'être cohérents dans le style que vous donnez aux noms des éléments que vous définissez. Par exemple, essayez de toujours garder dans le même ordre les noms et les verbes. Si vous appelez une méthode RechercherFichiersTexte(), nommez une autre méthode RechercherFichierImages() au lieu de FichiersImageRechercher(). 5. Nommage des Namespaces (espaces de noms). Le nom des namespaces est particulièrement important dans l'organisation de votre code et peut grandement faciliter et normer la manière dont les objets communiquent entre eux. De plus, une grande attention est nécessaire (surtout si vous développez des composants réutilisables) afin d'éviter toute collision possible entre le nom complet (c.à.d. le nom de tous les namespaces contenant + le nom de l'élément) de l'un de vos éléments et le nom d'un autre élément que vous n'avez pas développé. Par exemple, si vous utilisez le même nom de namespace pour un logiciel alors que ce nom est déjà utilisé dans un autre logiciel, des problèmes de collisions de noms risquent de se poser! De ce fait, la création d'un namespace de haut niveau (comme par exemple le nom de votre société) représente toujours une bonne solution de ce point de vue. Vous pourrez par la suite créer à l'intérieur du namespace de haut niveau, des namespaces successifs représentant la technologie, le département, ou encore la couche (couche d'accès aux données, couche métier, etc..) à laquelle sont destinées les classes contenues. Pour information, Microsoft recommande les namespaces commençant par : <NomDeSociété>.<NomLogiciel> Comme par exemple : ratp.métropolitain.personnel ratp.métropolitain.matériel ou 123

124 Annexe 2 : Caractères d'échappement Voici les séquences d'échappement que nous pouvons utiliser : Séquence d'échappement Caractère obtenu \' Simple guillemet \" Double guillemet \\ AntiSlash \0 Null \a Alerte (bip) \b Retour Arrière \f Nouvelle page \n Retour à la ligne \r Retour chariot \t Tabulation \v Tabulation verticale 124

125 Annexe 3 Noms et Mots-Clés Il est important que les noms de vos objets, méthodes, propriétés, etc.. n'entrent pas en conflit avec des mots-clés utilisés par le langage pour signifier quelque chose. Si vous essayez de nommer un élément avec un mot qui s'avère être un mot-clé, vous obtiendrez une erreur de syntaxe car le compilateur supposera que le nom est une instruction. De plus, comme le Framework.NET permet l'interopérabilité entre langages, il est également important de ne pas utiliser des mots-clés qui seraient des mots-clés dans d'autres langages.net. 1. Liste des mots-clés Visual Basic.NET Voici donc un tableau indiquant la liste des mots-clés utilisés en Visual Basic.NET et dont vous ne pourrez pas vous servir pour nommer des éléments de code en langage C#. Abs Do Loc RGB Add Double Local Right AddHandler Each Lock RmDir AddressOf Else LOF Rnd Alias ElseIf Log RTrim And Empty Long SaveSettings Ansi End Loop Second AppActivate Enum LTrim Seek Append EOF Me Select As Erase Mid SetAttr Assembly Error MIRR Shared Atan Event MkDir Shell Auto Exit Module Short Beep Exp Month Sign Binary Explicit MustInherit Sin BitAnd ExternalSource MustOverrride Single BitNot False MyBase SLN BitOr FileAttr MyClass Space BitXor FileCopy Namespace Spc Boolean FileDateTime New Split ByRef FileLen Next Sqrt Byte Filter Not Static ByVal Finally Nothing Step Call Fix NotInheritable Stop Case For NotOverridable Str Catch Format Now StrComp Cbool FreeFile Nper StrConv Cbyte Friend NPV Strict Cdate Function Null String CDbl FV Object Structure Cdec Get Oct Sub 125

126 ChDir GetAllSettings Off Switch ChDrive GetAttr On SYD Choose GetException Open SyncLock Chr GetObject Option Tab Cint GetSettings Optional Tan Class GetType Or Text Clear Goto Overloads Then CLng Handles Overridable Throw Close Hex Overrides TimeOfDay Collection Hour ParramArray Timer Command If Pmt TimeSerial Compare IIf PPmt TimeValue Const Implements Preserve To Cos Imports Print Today CreateObject In Private Trim Cshort Inherits Property Try Csng Input Public TypeName CStr InStr Put TypeOf CurDir Int PV Ubound Date Integer QBColor Ucase DateAdd Interface Raise Unicode DateDiff Ipmt RaiseEvent Unlock DatePart IRR Randomize Until DateSerial Is Rate Val DateValue IsArray Read WeekDay Day IsDate ReadOnly While DDB IsDbNull ReDim Width Decimal IsNumeric Remove With Declare Item RemoveHandler WithEvents Default Kill Rename Write Delegate LCase Replace WriteOnly DeleteSettings Left Reset Xor Dim Lib Resume Year Dir Line Return 126

127 2. Liste des mots-clés C# Comme vous allez pouvoir le constater, le langage C# comprend beaucoup moins de mots-clés que le langage Visual Basic.NET. Comme pour les mots-clés VB, tous les termes dans le tableau ci-dessous sont des mots-clés qu'il n'est pas possible d'utiliser comme identifiant en C#. abstract do implicit params switch as double in private this base else int protected throw bool enum interface public true break event internal readonly try byte explicit is ref typeof case extern lock return uint catch false long sbyte ulong char finally namespace sealed unchecked checked fixed new short unsafe class float null sizeof ushort const for object stackalloc using continue foreach operator static virtual decimal goto out string volatile default if override struct void delegate while 127

128 128

Généralités sur le Langage Java et éléments syntaxiques.

Généralités sur le Langage Java et éléments syntaxiques. Généralités sur le Langage Java et éléments syntaxiques. Généralités sur le Langage Java et éléments syntaxiques....1 Introduction...1 Genéralité sur le langage Java....1 Syntaxe de base du Langage...

Plus en détail

1. Introduction... 2. 2. Création d'une macro autonome... 2. 3. Exécuter la macro pas à pas... 5. 4. Modifier une macro... 5

1. Introduction... 2. 2. Création d'une macro autonome... 2. 3. Exécuter la macro pas à pas... 5. 4. Modifier une macro... 5 1. Introduction... 2 2. Création d'une macro autonome... 2 3. Exécuter la macro pas à pas... 5 4. Modifier une macro... 5 5. Création d'une macro associée à un formulaire... 6 6. Exécuter des actions en

Plus en détail

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère

Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère L'héritage et le polymorphisme en Java Pour signifier qu'une classe fille hérite d'une classe mère, on utilise le mot clé extends class fille extends mère En java, toutes les classes sont dérivée de la

Plus en détail

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java

Info0101 Intro. à l'algorithmique et à la programmation. Cours 3. Le langage Java Info0101 Intro. à l'algorithmique et à la programmation Cours 3 Le langage Java Pierre Delisle, Cyril Rabat et Christophe Jaillet Université de Reims Champagne-Ardenne Département de Mathématiques et Informatique

Plus en détail

ECLIPSE ET PDT (Php development tools)

ECLIPSE ET PDT (Php development tools) ECLIPSE ET PDT (Php development tools) Eclipse Eclipse est un IDE (Integrated Development Environment)).C estun projet de la Fondation Eclipse visant à développer tout un environnement de développement

Plus en détail

< Atelier 1 /> Démarrer une application web

< Atelier 1 /> Démarrer une application web MES ANNOTATIONS SONT EN ROUGE : Axel < Atelier 1 /> Démarrer une application web Microsoft France Tutorial Découverte de ASP.NET 2.0 Sommaire 1 INTRODUCTION... 3 1.1 CONTEXTE FONCTIONNEL... 3 1.2 CONTEXTE

Plus en détail

Java 7 Les fondamentaux du langage Java

Java 7 Les fondamentaux du langage Java 184 Java 7 Les fondamentaux du langage Java 1.1 Les bibliothèques graphiques Le langage Java propose deux bibliothèques dédiées à la conception d'interfaces graphiques. La bibliothèque AWT et la bibliothèque

Plus en détail

INTRODUCTION A JAVA. Fichier en langage machine Exécutable

INTRODUCTION A JAVA. Fichier en langage machine Exécutable INTRODUCTION A JAVA JAVA est un langage orienté-objet pur. Il ressemble beaucoup à C++ au niveau de la syntaxe. En revanche, ces deux langages sont très différents dans leur structure (organisation du

Plus en détail

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting

TD Objets distribués n 3 : Windows XP et Visual Studio.NET. Introduction à.net Remoting IUT Bordeaux 1 2005-2006 Département Informatique Licence Professionnelle ~ SI TD Objets distribués n 3 : Windows XP et Visual Studio.NET Introduction à.net Remoting Partie 1 : l'analyseur de performances

Plus en détail

TP1 : Initiation à Java et Eclipse

TP1 : Initiation à Java et Eclipse TP1 : Initiation à Java et Eclipse 1 TP1 : Initiation à Java et Eclipse Systèmes d Exploitation Avancés I. Objectifs du TP Ce TP est une introduction au langage Java. Il vous permettra de comprendre les

Plus en détail

Anne Tasso. Java. Le livre de. premier langage. 10 e édition. Avec 109 exercices corrigés. Groupe Eyrolles, 2000-2015, ISBN : 978-2-212-14154-2

Anne Tasso. Java. Le livre de. premier langage. 10 e édition. Avec 109 exercices corrigés. Groupe Eyrolles, 2000-2015, ISBN : 978-2-212-14154-2 Anne Tasso Java Le livre de premier langage 10 e édition Avec 109 exercices corrigés Groupe Eyrolles, 2000-2015, ISBN : 978-2-212-14154-2 Table des matières Avant-propos Organisation de l ouvrage..............................

Plus en détail

Microsoft Application Center Test

Microsoft Application Center Test Microsoft Application Center Test L'outil de Test de performance des Sites Web Avec Visual Studio.NET, il est fourni une petite application qui permet de valider la performance de son site Internet ou

Plus en détail

SHERLOCK 7. Version 1.2.0 du 01/09/09 JAVASCRIPT 1.5

SHERLOCK 7. Version 1.2.0 du 01/09/09 JAVASCRIPT 1.5 SHERLOCK 7 Version 1.2.0 du 01/09/09 JAVASCRIPT 1.5 Cette note montre comment intégrer un script Java dans une investigation Sherlock et les différents aspects de Java script. S T E M M E R I M A G I N

Plus en détail

Programmer en JAVA. par Tama ([email protected]( [email protected])

Programmer en JAVA. par Tama (tama@via.ecp.fr( tama@via.ecp.fr) Programmer en JAVA par Tama ([email protected]( [email protected]) Plan 1. Présentation de Java 2. Les bases du langage 3. Concepts avancés 4. Documentation 5. Index des mots-clés 6. Les erreurs fréquentes

Plus en détail

Sql Server 2005 Reporting Services

Sql Server 2005 Reporting Services Sql Server 2005 Reporting Services Un grand merci à Mr F. B. pour sa franchise, son sens de la relation humaine et son humilité. Sql Server 2005 Reporting Services - 2 / 30 - Sommaire Sommaire...2 Introduction...3

Plus en détail

JAVA 8. JAVA 8 - Les fondamentaux du langage. Les fondamentaux du langage Java. Avec exercices pratiques et corrigés JAVA 8 29,90.

JAVA 8. JAVA 8 - Les fondamentaux du langage. Les fondamentaux du langage Java. Avec exercices pratiques et corrigés JAVA 8 29,90. Analyste et développeur pendant plus de 10 ans, Thierry GROUSSARD s est ensuite orienté vers la formation et plus particulièrement dans le domaine du développement. Sa connaissance approfondie des besoins

Plus en détail

Chapitre 2. Classes et objets

Chapitre 2. Classes et objets Chapitre 2: Classes et Objets 1/10 Chapitre 2 Classes et objets Chapitre 2: Classes et Objets 2/10 Approche Orientée Objet Idée de base de A.O.O. repose sur l'observation de la façon dont nous procédons

Plus en détail

UE Programmation Impérative Licence 2ème Année 2014 2015

UE Programmation Impérative Licence 2ème Année 2014 2015 UE Programmation Impérative Licence 2 ème Année 2014 2015 Informations pratiques Équipe Pédagogique Florence Cloppet Neilze Dorta Nicolas Loménie [email protected] 2 Programmation Impérative

Plus en détail

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java

Cours 1 : Introduction. Langages objets. but du module. contrôle des connaissances. Pourquoi Java? présentation du module. Présentation de Java Langages objets Introduction M2 Pro CCI, Informatique Emmanuel Waller, LRI, Orsay présentation du module logistique 12 blocs de 4h + 1 bloc 2h = 50h 1h15 cours, 45mn exercices table, 2h TD machine page

Plus en détail

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile

TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile TP n 2 Concepts de la programmation Objets Master 1 mention IL, semestre 2 Le type Abstrait Pile Dans ce TP, vous apprendrez à définir le type abstrait Pile, à le programmer en Java à l aide d une interface

Plus en détail

Annexe : La Programmation Informatique

Annexe : La Programmation Informatique GLOSSAIRE Table des matières La Programmation...2 Les langages de programmation...2 Java...2 La programmation orientée objet...2 Classe et Objet...3 API et Bibliothèque Logicielle...3 Environnement de

Plus en détail

Plan du cours. Historique du langage http://www.oracle.com/technetwork/java/index.html. Nouveautés de Java 7

Plan du cours. Historique du langage http://www.oracle.com/technetwork/java/index.html. Nouveautés de Java 7 Université Lumière Lyon 2 Faculté de Sciences Economiques et Gestion KHARKIV National University of Economic Introduction au Langage Java Master Informatique 1 ère année Julien Velcin http://mediamining.univ-lyon2.fr/velcin

Plus en détail

Module.NET 3 Les Assemblys.NET

Module.NET 3 Les Assemblys.NET Module.NET Chapitre 3 Les Assemblys.NET 2011/2012 Page 1 sur 13 Contenu Cours... 3 3.1 - Définition d un assembly.net... 3 3.2 - Private assembly ou assembly privé.... 3 3.3 - Shared assembly ou assembly

Plus en détail

TD/TP 1 Introduction au SDK d Android

TD/TP 1 Introduction au SDK d Android TD/TP 1 Introduction au SDK d Android Romain Raveaux 1 Introduction Android est un système d'exploitation pour téléphone portable de nouvelle génération développé par Google. Celui-ci met à disposition

Plus en détail

PRODIGE V3. Manuel utilisateurs. Consultation des métadonnées

PRODIGE V3. Manuel utilisateurs. Consultation des métadonnées PRODIGE V3 Manuel utilisateurs Consultation des métadonnées Pour plus d'information sur le dispositif : à remplir par chaque site éventuellement 2 PRODIGE V3 : Consultation des métadonnées SOMMAIRE 1.

Plus en détail

Créer et partager des fichiers

Créer et partager des fichiers Créer et partager des fichiers Le rôle Services de fichiers... 246 Les autorisations de fichiers NTFS... 255 Recherche de comptes d utilisateurs et d ordinateurs dans Active Directory... 262 Délégation

Plus en détail

Qlik Sense Desktop. Qlik Sense 2.0.2 Copyright 1993-2015 QlikTech International AB. Tous droits réservés.

Qlik Sense Desktop. Qlik Sense 2.0.2 Copyright 1993-2015 QlikTech International AB. Tous droits réservés. Qlik Sense Desktop Qlik Sense 2.0.2 Copyright 1993-2015 QlikTech International AB. Tous droits réservés. Copyright 1993-2015 QlikTech International AB. Tous droits réservés. Qlik, QlikTech, Qlik Sense,

Plus en détail

Notions fondamentales du langage C# Version 1.0

Notions fondamentales du langage C# Version 1.0 Notions fondamentales du langage C# Version 1.0 Z 2 [Notions fondamentales du langage Csharp] [Date : 25/03/09] Sommaire 1 Tout ce qu il faut savoir pour bien commencer... 3 1.1 Qu est ce qu un langage

Plus en détail

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie

Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie Chapitre I : Les bases du C++ Le langage C++ est un langage de programmation puissant, polyvalent, on serait presque tenté de dire universel, massivement utilisé dans l'industrie du logiciel, et ce depuis

Plus en détail

Gérer, stocker et partager vos photos grâce à Picasa. Janvier 2015

Gérer, stocker et partager vos photos grâce à Picasa. Janvier 2015 Gérer, stocker et partager vos photos grâce à Picasa Janvier 2015 Sommaire 1 - Découverte de Picasa 2 - Gestion des dossiers et des photos 3 - Trier, filtrer et rechercher 4 - Retoucher une image 5 - Création

Plus en détail

Table des matières. 1 À propos de ce manuel...5 1.1 Icônes utilisées dans ce manuel... 5. 1.2 Public visé... 5. 1.3 Commentaires...

Table des matières. 1 À propos de ce manuel...5 1.1 Icônes utilisées dans ce manuel... 5. 1.2 Public visé... 5. 1.3 Commentaires... Manuel utilisateur Table des matières 1 À propos de ce manuel...5 1.1 Icônes utilisées dans ce manuel... 5 1.2 Public visé... 5 1.3 Commentaires... 5 2 Généralités sur les applications web... 7 3 Module

Plus en détail

EXCEL PERFECTIONNEMENT SERVICE INFORMATIQUE. Version 1.0 30/11/05

EXCEL PERFECTIONNEMENT SERVICE INFORMATIQUE. Version 1.0 30/11/05 EXCEL PERFECTIONNEMENT Version 1.0 30/11/05 SERVICE INFORMATIQUE TABLE DES MATIERES 1RAPPELS...3 1.1RACCOURCIS CLAVIER & SOURIS... 3 1.2NAVIGUER DANS UNE FEUILLE ET UN CLASSEUR... 3 1.3PERSONNALISER LA

Plus en détail

MEGA ITSM Accelerator. Guide de Démarrage

MEGA ITSM Accelerator. Guide de Démarrage MEGA ITSM Accelerator Guide de Démarrage MEGA 2009 SP4 1ère édition (juin 2010) Les informations contenues dans ce document pourront faire l objet de modifications sans préavis et ne sauraient en aucune

Plus en détail

TP1. Outils Java Eléments de correction

TP1. Outils Java Eléments de correction c sep. 2008, v2.1 Java TP1. Outils Java Eléments de correction Sébastien Jean Le but de ce TP, sur une séance, est de se familiariser avec les outils de développement et de documentation Java fournis par

Plus en détail

DotNet. Plan. Les outils de développement

DotNet. Plan. Les outils de développement DotNet Les outils de développement Version 1.03 du 16/10/2006 par Jacky Renno Plan La machine virtuelle Le kit de développement Le kit de langage Le Visual Studio.NET Le serveur web IIS 6.0 Le modeleur

Plus en détail

Eclipse atelier Java

Eclipse atelier Java Eclipse atelier Java Table des matières 1. Introduction...2 2. Télécharger eclipse...3 3. Installer eclipse...3 4. Premier lancement d eclipse...3 5. Configurer eclipse pour faire du Java...5 6. Développer

Plus en détail

SOMMAIRE 1 INTRODUCTION 4 2 GUIDE D UTILISATION ET TUTORIAUX VIDEOS EN LIGNE 4 3 CONTACTER VOTRE SUPPORT 4 4 RACCOURCIS CLAVIER 5

SOMMAIRE 1 INTRODUCTION 4 2 GUIDE D UTILISATION ET TUTORIAUX VIDEOS EN LIGNE 4 3 CONTACTER VOTRE SUPPORT 4 4 RACCOURCIS CLAVIER 5 SOMMAIRE 1 INTRODUCTION 4 2 GUIDE D UTILISATION ET TUTORIAUX VIDEOS EN LIGNE 4 3 CONTACTER VOTRE SUPPORT 4 4 RACCOURCIS CLAVIER 5 5 ADMINISTRER SON SITE WEBGAZELLE CMS 2.0 5 5.1 Configuration minimale

Plus en détail

Module SMS pour Microsoft Outlook MD et Outlook MD Express. Guide d'aide. Guide d'aide du module SMS de Rogers Page 1 sur 40 Tous droits réservés

Module SMS pour Microsoft Outlook MD et Outlook MD Express. Guide d'aide. Guide d'aide du module SMS de Rogers Page 1 sur 40 Tous droits réservés Module SMS pour Microsoft Outlook MD et Outlook MD Express Guide d'aide Guide d'aide du module SMS de Rogers Page 1 sur 40 Table des matières 1. Exigences minimales :...3 2. Installation...4 1. Téléchargement

Plus en détail

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE 2 ème partie : REQUÊTES Sommaire 1. Les REQUÊTES...2 1.1 Créer une requête simple...2 1.1.1 Requête de création de listage ouvrages...2 1.1.2 Procédure de

Plus en détail

Avant-propos FICHES PRATIQUES EXERCICES DE PRISE EN MAIN CAS PRATIQUES

Avant-propos FICHES PRATIQUES EXERCICES DE PRISE EN MAIN CAS PRATIQUES Avant-propos Conçu par des pédagogues expérimentés, son originalité est d être à la fois un manuel de formation et un manuel de référence complet présentant les bonnes pratiques d utilisation. FICHES PRATIQUES

Plus en détail

Guide d'utilisation du Serveur USB

Guide d'utilisation du Serveur USB Guide d'utilisation du Serveur USB Copyright 20-1 - Informations de copyright Copyright 2010. Tous droits réservés. Avis de non responsabilité Incorporated ne peut être tenu responsable des erreurs techniques

Plus en détail

Héritage presque multiple en Java (1/2)

Héritage presque multiple en Java (1/2) Héritage presque multiple en Java (1/2) Utiliser deux classes ou plus dans la définition d'une nouvelle classe peut se faire par composition. class Etudiant{ int numero; Diplome d; float passeexamen(examen

Plus en détail

Objet du document. Version document : 1.00

Objet du document. Version document : 1.00 Version document : 1.00 Objet du document Les dix points de cet article constituent les règles à connaitre pour intégrer une application au sein d AppliDis. Le site des Experts Systancia comporte également

Plus en détail

Créer le schéma relationnel d une base de données ACCESS

Créer le schéma relationnel d une base de données ACCESS Utilisation du SGBD ACCESS Polycopié réalisé par Chihab Hanachi et Jean-Marc Thévenin Créer le schéma relationnel d une base de données ACCESS GENERALITES SUR ACCESS... 1 A PROPOS DE L UTILISATION D ACCESS...

Plus en détail

v7.1 SP2 Guide des Nouveautés

v7.1 SP2 Guide des Nouveautés v7.1 SP2 Guide des Nouveautés Copyright 2012 Sage Technologies Limited, éditeur de ce produit. Tous droits réservés. Il est interdit de copier, photocopier, reproduire, traduire, copier sur microfilm,

Plus en détail

HelpAndManual_unregistered_evaluation_copy GESTIONNAIRE D'ALARMES CENTRALISE OPTIM'ALARM. Manuel d'utilisation

HelpAndManual_unregistered_evaluation_copy GESTIONNAIRE D'ALARMES CENTRALISE OPTIM'ALARM. Manuel d'utilisation HelpAndManual_unregistered_evaluation_copy GESTIONNAIRE D'ALARMES CENTRALISE OPTIM'ALARM Manuel d'utilisation OPTIMALOG 2008 Table des matières I Table des matières Part I Gestionnaire d'alarmes Optim'Alarm

Plus en détail

MO-Call pour les Ordinateurs. Guide de l utilisateur

MO-Call pour les Ordinateurs. Guide de l utilisateur MO-Call pour les Ordinateurs Guide de l utilisateur Sommaire MO-CALL POUR ORDINATEURS...1 GUIDE DE L UTILISATEUR...1 SOMMAIRE...2 BIENVENUE CHEZ MO-CALL...4 MISE EN ROUTE...5 CONNEXION...5 APPELS...7 COMPOSITION

Plus en détail

Sage CRM. 7.2 Guide de Portail Client

Sage CRM. 7.2 Guide de Portail Client Sage CRM 7.2 Guide de Portail Client Copyright 2013 Sage Technologies Limited, éditeur de ce produit. Tous droits réservés. Il est interdit de copier, photocopier, reproduire, traduire, copier sur microfilm,

Plus en détail

Reporting Services - Administration

Reporting Services - Administration Reporting Services - Administration Comment administrer SQL Server Reporting Services Cet article a pour but de présenter comment gérer le serveur depuis le "portail" de Reporting Services. Nous verrons

Plus en détail

SQL Server Installation Center et SQL Server Management Studio

SQL Server Installation Center et SQL Server Management Studio SQL Server Installation Center et SQL Server Management Studio Version 1.0 Grégory CASANOVA 2 SQL Server Installation Center et SQL Server Management Studio [03/07/09] Sommaire 1 Installation de SQL Server

Plus en détail

Création d'un site dynamique en PHP avec Dreamweaver et MySQL

Création d'un site dynamique en PHP avec Dreamweaver et MySQL Création d'un site dynamique en PHP avec Dreamweaver et MySQL 1. Création et configuration du site 1.1. Configuration de Dreamweaver Avant de commencer, il est nécessaire de connaître l'emplacement du

Plus en détail

Edutab. gestion centralisée de tablettes Android

Edutab. gestion centralisée de tablettes Android Edutab gestion centralisée de tablettes Android Résumé Ce document présente le logiciel Edutab : utilisation en mode enseignant (applications, documents) utilisation en mode administrateur (configuration,

Plus en détail

Corrigé de l'atelier pratique du module 6 : Transfert de données

Corrigé de l'atelier pratique du module 6 : Transfert de données Corrigé de l'atelier pratique du module 6 : Transfert de données Table des matières Atelier pratique 6 : Transfert de données 1 Exercice 1 : Création d'un package SSIS 1 Exercice 2 : Déploiement d'un package

Plus en détail

Freeway 7. Nouvelles fonctionnalités

Freeway 7. Nouvelles fonctionnalités ! Freeway 7 Nouvelles fonctionnalités À propos de ce guide... 3 Nouvelles fonctionnalités en un coup d'oeil... 3 À propos de la conception d'un site web réactif... 3 Travailler avec les pages pour créer

Plus en détail

Publipostage avec Calc

Publipostage avec Calc Auto-formation sur OpenOffice.org 2.0 par Cyril Beaussier Version 1.0.2 - Avril 2006 Publipostage avec Calc Sommaire Introduction... 2 Présentation... 3 Notions... 4 Les données... 5 Lettre type... 7 Création

Plus en détail

Utilisation de l'outil «Open Office TEXTE»

Utilisation de l'outil «Open Office TEXTE» PRESENTATION / FORMATION Utilisation de l'outil «Open Office TEXTE» Présentation générale : OpenOffice Texte est un traitement de texte assez similaire à celui proposé par Microsoft ; il est d'ailleurs

Plus en détail

Onglet sécurité de Windows XP Pro et XP Home

Onglet sécurité de Windows XP Pro et XP Home Onglet sécurité de Windows XP Pro et XP Home Quelle peut être la raison du manque de l'onglet "sécurité"? Des amis ont XP Pro et je n'ai pu trouver l'onglet "sécurité" pour gérer les droits d'un fichier.

Plus en détail

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP

INITIATION AU LANGAGE C SUR PIC DE MICROSHIP COURS PROGRAMMATION INITIATION AU LANGAGE C SUR MICROCONTROLEUR PIC page 1 / 7 INITIATION AU LANGAGE C SUR PIC DE MICROSHIP I. Historique du langage C 1972 : naissance du C dans les laboratoires BELL par

Plus en détail

LANDPARK NETWORK IP LANDPARK NETWORK IP VOUS PERMET D'INVENTORIER FACILEMENT VOS POSTES EN RÉSEAU

LANDPARK NETWORK IP LANDPARK NETWORK IP VOUS PERMET D'INVENTORIER FACILEMENT VOS POSTES EN RÉSEAU LANDPARK NETWORK IP Avril 2014 LANDPARK NETWORK IP VOUS PERMET D'INVENTORIER FACILEMENT VOS POSTES EN RÉSEAU Landpark NetworkIP est composé de trois modules : Un module Serveur, que l'on installe sur n'importe

Plus en détail

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE

CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE CRÉER UNE BASE DE DONNÉES AVEC OPEN OFFICE BASE 3. ème partie : RAPPORTS MENU D'ACCUEIL - MIGRATION Table des matières 1. Les RAPPORTS...2 1.1 Création d'un rapport basé sur une Requête...3 1.2 Imprimer,

Plus en détail

l'ordinateur les bases

l'ordinateur les bases l'ordinateur les bases Démarrage de l'ordinateur - Le bureau, mon espace de travail - J'utilise la souris - Ouvertes ou fermées, les fenêtres - Dans l'ordinateur, tout est fichier - Le clavier : écrire,

Plus en détail

KAJOUT WASSIM INTERNET INFORMATION SERVICES (IIS) 01/03/2013. Compte-rendu sur ISS KAJOUT Wassim

KAJOUT WASSIM INTERNET INFORMATION SERVICES (IIS) 01/03/2013. Compte-rendu sur ISS KAJOUT Wassim 01/03/2013 Le rôle de Serveur Web (IIS) dans Windows Server 2008 R2 vous permet de partager des informations avec des utilisateurs sur Internet, sur un intranet ou un extranet. Windows Server 2008 R2 met

Plus en détail

Guide utilisateur Archivage intermédiaire Messagerie. Enterprise Connect pour Outlook 2010 EC 10.2.1 V 1.0

Guide utilisateur Archivage intermédiaire Messagerie. Enterprise Connect pour Outlook 2010 EC 10.2.1 V 1.0 Guide utilisateur Archivage intermédiaire Messagerie Enterprise Connect pour Outlook 2010 EC 10.2.1 V 1.0 Page : 2/38 Table des matières 1. Introduction... 3 2. L'interface Livelink dans MS Outlook...

Plus en détail

GUIDE Excel (version débutante) Version 2013

GUIDE Excel (version débutante) Version 2013 Table des matières GUIDE Excel (version débutante) Version 2013 1. Créer un nouveau document Excel... 3 2. Modifier un document Excel... 3 3. La fenêtre Excel... 4 4. Les rubans... 4 5. Saisir du texte

Plus en détail

Manuel d utilisation email NETexcom

Manuel d utilisation email NETexcom Manuel d utilisation email NETexcom Table des matières Vos emails avec NETexcom... 3 Présentation... 3 GroupWare... 3 WebMail emails sur internet... 4 Se connecter au Webmail... 4 Menu principal... 5 La

Plus en détail

Évaluation des compétences. Identification du contenu des évaluations. Septembre 2014

Évaluation des compétences. Identification du contenu des évaluations. Septembre 2014 Identification du contenu des évaluations Septembre 2014 Tous droits réservés : Université de Montréal Direction des ressources humaines Table des matières Excel Base version 2010... 1 Excel intermédiaire

Plus en détail

LibreOffice Calc : introduction aux tableaux croisés dynamiques

LibreOffice Calc : introduction aux tableaux croisés dynamiques Fiche logiciel LibreOffice Calc 3.x Tableur Niveau LibreOffice Calc : introduction aux tableaux croisés dynamiques Un tableau croisé dynamique (appelé Pilote de données dans LibreOffice) est un tableau

Plus en détail

Cours Access 1) INTRODUCTION AU SGBD...4 2) LES TABLES...4

Cours Access 1) INTRODUCTION AU SGBD...4 2) LES TABLES...4 COURS MS ACCESS 1) INTRODUCTION AU SGBD...4 A) DÉFINITION...4 B) ENREGISTREMENTS ET CHAMPS....4 C) LES GRANDES FONCTIONS D'ACCESS... 4 i) Les tables...4 ii) Les requêtes...4 iii) Les formulaires... 4 iv)

Plus en détail

Le langage C. Séance n 4

Le langage C. Séance n 4 Université Paris-Sud 11 Institut de Formation des Ingénieurs Remise à niveau INFORMATIQUE Année 2007-2008 Travaux pratiques d informatique Le langage C Séance n 4 But : Vous devez maîtriser à la fin de

Plus en détail

F O R M A T I O N S LOTUS NOTES. 8.5 Utilisateurs. 02 40 42 33 37 13 rue de la Bôle. E U R L. a u c a p i t a l d e 1 0 0 0

F O R M A T I O N S LOTUS NOTES. 8.5 Utilisateurs. 02 40 42 33 37 13 rue de la Bôle. E U R L. a u c a p i t a l d e 1 0 0 0 Bureautique - Internet - Développement ALTAIRE F O R M A T I O N S Logiciels - Audit - Marketing LOTUS NOTES 8.5 Utilisateurs 02 40 42 33 37 13 rue de la Bôle 44510 le Pouliguen altair.formation s@wan

Plus en détail

Guide pas à pas pour l'utilisation de la Console de gestion des stratégies de groupe

Guide pas à pas pour l'utilisation de la Console de gestion des stratégies de groupe Page 1 sur 16 Guide pas à pas pour l'utilisation de la Console de gestion des stratégies de groupe Paru le 17/09/2004 Ce guide pas à pas explique comment utiliser la Console de gestion des stratégies de

Plus en détail

Corrigé de l'atelier pratique du module 8 : Implémentation de la réplication

Corrigé de l'atelier pratique du module 8 : Implémentation de la réplication Corrigé de l'atelier pratique du module 8 : Implémentation de la réplication Table des matières Atelier pratique 8 : Implémentation de la réplication 1 Exercice 1 : Création d'une publication 1 Exercice

Plus en détail

as Architecture des Systèmes d Information

as Architecture des Systèmes d Information Plan Plan Programmation - Introduction - Nicolas Malandain March 14, 2005 Introduction à Java 1 Introduction Présentation Caractéristiques Le langage Java 2 Types et Variables Types simples Types complexes

Plus en détail

Cours 420-KEG-LG, Gestion de réseaux et support technique. Atelier No2 :

Cours 420-KEG-LG, Gestion de réseaux et support technique. Atelier No2 : Atelier No2 : Installation d Active Directory Installation du service DNS Installation du Service WINS Création d'un compte d'ordinateur Jonction d'un ordinateur à un domaine Création d usagers. Étape

Plus en détail

Algorithmique et Programmation, IMA

Algorithmique et Programmation, IMA Algorithmique et Programmation, IMA Cours 2 : C Premier Niveau / Algorithmique Université Lille 1 - Polytech Lille Notations, identificateurs Variables et Types de base Expressions Constantes Instructions

Plus en détail

Langage Java. Classe de première SI

Langage Java. Classe de première SI Langage Java Table des matières 1. Premiers pas...2 1.1. Introduction...2 1.2. Mon premier programme...2 1.3. Les commentaires...2 2. Les variables et les opérateurs...2 3. La classe Scanner...3 4. Les

Plus en détail

Tune Sweeper Manuel de l'utilisateur

Tune Sweeper Manuel de l'utilisateur Tune Sweeper Manuel de l'utilisateur www.wideanglesoftware.com Table des matières Introduction 2 Démarrage rapide 5 Recherche de doublons 9 Sélection des pistes à conserver 12 Éliminer les doublons 15

Plus en détail

:...2 I.6. :... 2 I.7. :... 2 I.8. :...3 I.9. :... 3 I.10. :... 3 II. 4 II.1.

:...2 I.6. :... 2 I.7. :... 2 I.8. :...3 I.9. :... 3 I.10. :... 3 II. 4 II.1. REPUBLIQUE ALGERIENNE DEMOCRATIQUE ET POPULAIRE MINISTERE DE LA FORMATION PROFESSIONNELLE INSTITUT DE LA FORMATION PROFESSIONNELLE DE BIRKHADEM Microsoft Outlook Mai 2004 IFP BIRKHADEM, Rue des trois frères

Plus en détail

Documentation utilisateur, manuel utilisateur MagicSafe Linux. Vous pouvez télécharger la dernière version de ce document à l adresse suivante :

Documentation utilisateur, manuel utilisateur MagicSafe Linux. Vous pouvez télécharger la dernière version de ce document à l adresse suivante : Documentation utilisateur, manuel utilisateur MagicSafe Linux. Vous pouvez télécharger la dernière version de ce document à l adresse suivante : http://www.hegerys.com/documentation/magicsafe-windows-doc.pdf

Plus en détail

FICHIERS ET DOSSIERS

FICHIERS ET DOSSIERS La différence entre fichier et dossier FICHIERS ET DOSSIERS La première notion à acquérir est la différence entre un dossier et un fichier Un dossier est une sorte de classeur dans lequel on range divers

Plus en détail

INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX

INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX TABLE DES MATIERES Livret Utilisateur Excel 2007 Niveau 2 INSERER DES OBJETS - LE RUBAN INSERTION... 3 TABLEAUX... 4 Les tableaux croisés dynamiques... 4 Création d un tableau croisé... 5 Comparer des

Plus en détail

Programmation Objet - Cours II

Programmation Objet - Cours II Programmation Objet - Cours II - Exercices - Page 1 Programmation Objet - Cours II Exercices Auteur : E.Thirion - Dernière mise à jour : 05/07/2015 Les exercices suivants sont en majorité des projets à

Plus en détail

EXCEL TUTORIEL 2012/2013

EXCEL TUTORIEL 2012/2013 EXCEL TUTORIEL 2012/2013 Excel est un tableur, c est-à-dire un logiciel de gestion de tableaux. Il permet de réaliser des calculs avec des valeurs numériques, mais aussi avec des dates et des textes. Ainsi

Plus en détail

Premiers Pas en Programmation Objet : les Classes et les Objets

Premiers Pas en Programmation Objet : les Classes et les Objets Chapitre 2 Premiers Pas en Programmation Objet : les Classes et les Objets Dans la première partie de ce cours, nous avons appris à manipuler des objets de type simple : entiers, doubles, caractères, booléens.

Plus en détail

Créer une base de données

Créer une base de données Access Créer une base de données SOMMAIRE Généralités sur les bases de données... 3 Création de la base de données... 4 A) Lancement d'access... 4 B) Enregistrement de la base de données vide... 4 Création

Plus en détail

Licence ST Université Claude Bernard Lyon I LIF1 : Algorithmique et Programmation C Bases du langage C 1 Conclusion de la dernière fois Introduction de l algorithmique générale pour permettre de traiter

Plus en détail

TeamViewer 7 Manuel Manager

TeamViewer 7 Manuel Manager TeamViewer 7 Manuel Manager TeamViewer GmbH Kuhnbergstraße 16 D-73037 Göppingen teamviewer.com Présentation Sommaire Sommaire... 2 1 Présentation... 4 1.1 À propos de TeamViewer Manager... 4 1.2 À propos

Plus en détail

Guide de déploiement

Guide de déploiement Guide de déploiement Installation du logiciel - Table des matières Présentation du déploiement du logiciel CommNet Server Windows Cluster Windows - Serveur virtuel CommNet Agent Windows Cluster Windows

Plus en détail

SAP Lumira Version du document : 1.23 2015-03-06. Guide de l'utilisateur de SAP Lumira

SAP Lumira Version du document : 1.23 2015-03-06. Guide de l'utilisateur de SAP Lumira SAP Lumira Version du document : 1.23 2015-03-06 Contenu 1 A propos de SAP Lumira....6 2 Guide de démarrage de SAP Lumira.... 7 2.1 Menus sur la page d'accueil.... 7 2.2 Étapes générales pour la visualisation

Plus en détail

MANUEL WORDPRESS. Objectif: Refonte d un site web sous Wordpress I PRE-REQUIS: 1 / Créer un backup (sauvegarde) du site:

MANUEL WORDPRESS. Objectif: Refonte d un site web sous Wordpress I PRE-REQUIS: 1 / Créer un backup (sauvegarde) du site: MANUEL WORDPRESS Objectif: Refonte d un site web sous Wordpress I PRE-REQUIS: 1 / Créer un backup (sauvegarde) du site: A/ Traitement de la base de données: Pour cette étape, vous aurez besoin au préalable

Plus en détail

Traitement de texte : Quelques rappels de quelques notions de base

Traitement de texte : Quelques rappels de quelques notions de base Traitement de texte : Quelques rappels de quelques notions de base 1 Quelques rappels sur le fonctionnement du clavier Voici quelques rappels, ou quelques appels (selon un de mes profs, quelque chose qui

Plus en détail

Google Drive, le cloud de Google

Google Drive, le cloud de Google Google met à disposition des utilisateurs ayant un compte Google un espace de 15 Go. Il est possible d'en obtenir plus en payant. // Google Drive sur le web Se connecter au site Google Drive A partir de

Plus en détail

Stellar Phoenix Outlook PST Repair - Technical 5.0 Guide d'installation

Stellar Phoenix Outlook PST Repair - Technical 5.0 Guide d'installation Stellar Phoenix Outlook PST Repair - Technical 5.0 Guide d'installation 1 Présentation Stellar Phoenix Outlook PST Repair - Technical offre une solution complète pour la récupération de données à partir

Plus en détail

1. Introduction...2. 2. Création d'une requête...2

1. Introduction...2. 2. Création d'une requête...2 1. Introduction...2 2. Création d'une requête...2 3. Définition des critères de sélection...5 3.1 Opérateurs...5 3.2 Les Fonctions...6 3.3 Plusieurs critères portant sur des champs différents...7 3.4 Requête

Plus en détail

Premiers pas sur e-lyco

Premiers pas sur e-lyco Premiers pas sur e-lyco A destination des parents, ce document présente les premiers éléments pour accéder aux services de l'ent e-lyco d'un lycée. Que signifient ENT et e-lyco? ENT = Espace ou Environnement

Plus en détail

Didacticiel de mise à jour Web

Didacticiel de mise à jour Web Didacticiel de mise à jour Web Copyright 1995-2012 Esri All rights reserved. Table of Contents Didacticiel : Création d'une application de mise à jour Web.................. 0 Copyright 1995-2012 Esri.

Plus en détail

IBM SPSS Statistics Version 22. Instructions d'installation sous Windows (licence nominative)

IBM SPSS Statistics Version 22. Instructions d'installation sous Windows (licence nominative) IBM SPSS Statistics Version 22 Instructions d'installation sous Windows (licence nominative) Table des matières Instructions d'installation....... 1 Configuration requise........... 1 Code d'autorisation...........

Plus en détail

Télécharger et Installer OpenOffice.org sous Windows

Télécharger et Installer OpenOffice.org sous Windows Télécharger et Installer OpenOffice.org sous Windows Version Date Auteur Commentaires 1.00 15/11/2008 Denis Bourdillon Création du document. Mise en forme de texte 1/15 Saison 2008-2009 Table des matières

Plus en détail

Module d introduction Comment réaliser vos propres cartes avec ArcGIS Online

Module d introduction Comment réaliser vos propres cartes avec ArcGIS Online Module d introduction Comment réaliser vos propres cartes avec ArcGIS Online Table des matières 1 Commencer avec ArcGis Online... 2 2 Créer des cartes I (utiliser les cartes disponibles /les services de

Plus en détail

Programme «Analyste Programmeur» Diplôme d état : «Développeur Informatique» Homologué au niveau III (Bac+2) (JO N 176 du 1 août 2003) (34 semaines)

Programme «Analyste Programmeur» Diplôme d état : «Développeur Informatique» Homologué au niveau III (Bac+2) (JO N 176 du 1 août 2003) (34 semaines) Programme «Analyste Programmeur» Diplôme d état : «Développeur Informatique» Homologué au niveau III (Bac+2) (JO N 176 du 1 août 2003) (34 semaines) Module 1 : Programmer une application informatique Durée

Plus en détail