FAQ C#Consultez toutes les FAQ
Nombre d'auteurs : 41, nombre de questions : 274, dernière mise à jour : 27 mai 2018 Ajouter une question
Cette FAQ a été réalisée pour répondre aux questions les plus fréquemment posées concernant C# sur le forum Développement DotNET
Je tiens à souligner qu'elle ne garantit en aucun cas que les informations qu'elle contient sont correctes ; les auteurs font le maximum, mais l'erreur est humaine. Si vous trouvez une erreur, ou que vous souhaitez devenir rédacteur, lisez ceci .
Sur ce, je vous souhaite une bonne lecture.
Commentez cette FAQ : Commentez
- Qu'est-ce que le .NET Framework ?
- Comment obtenir la version de mon application ?
- Comment convertir un objet d'un type de base en un objet d'un autre type de base ?
- Comment lire et écrire des données sur la console ?
- Comment modifier le titre de la console ?
- Comment fonctionne le Garbage Collector ?
- Comment forcer la libération de la mémoire par le Garbage Collector ?
- Comment puis-je appeler une fonction présente dans une DLL win32 ?
- Comment obtenir le répertoire où se trouve mon application ?
- Comment récupérer le chemin de l'application ?
- Comment obtenir le répertoire courant ?
- Comment obtenir la ligne de commande de l'application ?
- Comment obtenir les variables d'environnement ?
- Comment ne lancer qu'une seule instance de mon application ?
- Comment ne lancer qu'une seule instance de mon application ? (2e technique)
- Comment générer des nombres aléatoires ?
- Comment utiliser des fichiers en tant que ressources dans un exe/dll ?
- Comment mesurer un intervalle de temps avec précision ?
Cette définition est tirée de MSDN.
.NET (lire dotnet) Framework est le modèle de programmation de la plateforme .NET. Les principaux composants de .NET Framework sont le Common Language Runtime et la bibliothèque de classes .NET Framework, qui contient ADO.NET, ASP.NET et Windows Forms. .NET Framework fournit un environnement d'exécution managé, un développement et un déploiement simplifiés et l'intégration à une grande variété de langages de programmation.
La version courante est la 3.5 SP1. La prochaine version, .NET 4.0, est actuellement disponible en beta 2, et la version finale devrait sortir le 12 avril 2010.
Pour obtenir la version de l'application courante, on utilise la classe System.Reflection.Assembly
Code c# : | Sélectionner tout |
1 2 3 4 5 | using System; using System.Reflection; Version ver = Assembly.GetEntryAssembly().GetName().Version); string myVer = ver.ToString(); |
La classe System.Convert permet de convertir des objets entre les principaux types de base du framework : d'un double vers un entier, d'une chaine de caractères vers un décimal, d'un entier vers un booléen…
Contrairement à un cast, la classe Convert est capable d'utiliser différentes techniques pour effectuer la conversion : un cast quand c'est possible, un appel de méthode (Parse, ToString), l'utilisation de l'interface IConvertible… Il est ainsi possible de convertir un objet dans le type voulu sans savoir quel est son type de départ.
La classe Convert peut aussi effectuer des conversions d'entiers en base 2, 8 ou 16, ou de convertir un tableau d'octets en base64.
Voici quelques exemples :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | // Conversion d'un entier vers une chaines de caractères int i = 10; string s = Convert.ToString(i); // ou plus simplement : // string s = i.ToString(); // Conversion d'une chaine vers un entier i = Convert.ToInt32(s); // Notez que si la conversion ne peut se faire, une exception est levée. // Ce serait le cas si s = "NonNumérique" // Conversion d'un entier en une chaine hexadécimale : s = Convert.ToString(i, 16); // Conversion d'un tableau d'octets en base64 : byte[] bytes = new byte[] { 0x23, 0xff, 0x40, 0xcc }; s = Convert.ToBase64String(bytes); |
Code c# : | Sélectionner tout |
1 2 | string s = "35000"; int i = int.Parse(s); |
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 | string s = "35000"; int i; if (int.TryParse(s, out i)) { // Conversion réussie } else { // Conversion échouée } |
Il vous faut utiliser la classe System.Console et les méthodes qui la compose.
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | public class SaisiTexte { private string _Texte; public static void Main() { Console.WriteLine("Saisissez un texte: "); _Texte = Console.ReadLine(); Console.WriteLine("Vous avez écrit : " + _Texte); } } |
- La console s'il y en a une active
- La fenêtre de debug (onglet Sortie - Déboguer) si l'application ne possède pas de console. Une application Windows Forms par exemple.
Pour ce qui est d'une application console, il faut passer par la classe Console avec la propriété Title :
Code c# : | Sélectionner tout |
Console.Title = "Mon titre";
Le garbage collector (aussi appelé ramasse-miettes) est le composant du framework chargé de gérer la mémoire utilisée par le programme. Il garde la trace des objets créés et des références à ces objets. Quand la mémoire occupée par le programme devient trop importante, le garbage collector effectue un cycle de collecte : il examine les objets en mémoire pour voir s'ils sont encore référencés. Si ce n'est pas le cas, ils sont inaccessibles et ne seront donc plus utilisés. Le garbage collector peut donc libérer la mémoire occupée par ces objets, ainsi que les autres ressources qu'ils utilisent (fichiers, connexions réseau, mémoire non managée...), en appelant le finaliseur (méthode Finalize, implémentée en C# sous la forme d'un destructeur).
Le garbage collector du .NET framework est de type « générationel » : cela signifie qu'il gère plusieurs générations d'objets. La première génération est constituée des objets récemment créés, qui sont susceptibles d'avoir une faible durée de vie ; c'est donc sur cette génération que la collecte est effectuée le plus souvent. Les objets qui « survivent » à un premier cycle de collecte sont promus à la deuxième génération, qui est collectée moins souvent. Les objets qui survivent à une deuxième collecte sont promus à la troisième et dernière génération, plus rarement collectée. Ce sont des objets qui ont une longue durée de vie, par exemple la fenêtre principale d'un programme. Ce mécanisme de générations permet de réduire le travail du garbage collector, qui est coûteux en ressources.
On croit souvent à tort que le garbage collector empêche les fuites mémoires : c'est faux ! Il facilite le travail du développeur car celui-ci n'a plus à se préoccuper de libérer la mémoire allouée, mais il faut garder à l'esprit qu'un objet ne sera pas collecté tant qu'il restera des références vers cet objet. Il faut donc bien penser à supprimer les références aux objets qu'on n'utilise plus, sinon ils resteront en mémoire jusqu'à la fin du programme.
Notez qu'il n'est pas possible de prévoir quand le garbage collector appelera le destructeur d'un objet qui n'est plus référencé : si un objet utilise des ressources systèmes critiques, il est donc préférable de libérer explicitement ces ressources le plus tôt possible. La technique recommandée pour gérer ces cas est d'implémenter l'interface IDisposable.
Pour forcer le Garbage Collector à libérer la mémoire inutilisée par le .NET Framework, on peut appeler la méthode Collect de la classe GC.
Code c# : | Sélectionner tout |
System.GC.Collect()
Par conséquent, ne le faites pas à moins d'être un expert du garbage collector.
Pour appeler une fonction présente dans une DLL, vous devez utiliser DllImport et vous devez toujours faire précéder le type de la méthode du mot-clé extern (cela permet de spécifier que la méthode est appelée dans un fichier externe à l'application).
Vous devez aussi connaître :
- le nom de la méthode ;
- le type qu'elle renvoie ;
- les paramètres qu'elle peut accepter.
Ces informations vous sont généralement fournies avec la documentation de la méthode désirée.
Voici un exemple de DllImport :
Code c# : | Sélectionner tout |
1 2 3 4 5 | using System.Runtime.InteropServices; //... [DllImport("user32.dll")] static extern int FlashWindow (int hwnd, int bInvert); |
Il y a différentes méthodes possibles :
- à l'aide de la méthode Environment.GetCommandLineArgs :
Code c# : Sélectionner tout 1
2
3
4
5// Chemin de l'exécutable // Le premier élément du tableau retourné est le chemin de l'exécutable string exePath = Environment.GetCommandLineArgs()[0]; // Répertoire de l'exécutable string exeDir = System.IO.Path.GetDirectoryName(exepath);
- avec Assembly.GetEntryAssembly() :
Code c# : Sélectionner tout 1
2string exePath = System.Reflection.Assembly.GetEntryAssembly().Location; string exeDir = System.IO.Path.GetDirectoryName(exePath);
- en Windows Forms, on peut aussi utiliser Application.StartupPath :
Code c# : Sélectionner tout string exeDir = Application.StartupPath;
Il faut pour cela récupérer le chemin de l'assembly contenant le code de démarrage de l'application :
Code c# : | Sélectionner tout |
string pathModule = System.IO.Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
Attention à ne pas confondre avec :
System.IO.Directory.GetCurrentDirectory(); |
On utilise la propriété CurrentDirectory de la classe Environment
Code c# : | Sélectionner tout |
1 2 | // Répertoire courant Console.WriteLine("Le répertoire courant est : {0}", Environment.CurrentDirectory); |
On utilise la propriété CommandLine de la classe Environment pour avoir la ligne entière dans une chaine de caractères :
Code c# : | Sélectionner tout |
Console.WriteLine("La ligne de commande est : {0}", Environment.CommandLine);
Code c# : | Sélectionner tout |
1 2 3 4 5 6 | // Arguments de ligne de commande Console.WriteLine("Arguments de ligne de commande"); string[] args = Environment.GetCommandLineArgs(); int j = args.Length; for (i = 0; i<j; i++) Console.WriteLine("Args({0}) = {1}", i, args[i]); |
On utilise les méthodes GetEnvironmentVariable et GetEnvironmentVariables de la classe Environment.
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 | // Obtenir une variable d'environement en particulier string userName = Environment.GetEnvironmentVariable("USERNAME"); // Enumérer toutes les variables d'environmeent foreach (DictionaryEntry de in Environment.GetEnvironmentVariables()) { Console.WriteLine("{0} = {1}", de.Key, de.Value); } |
Il arrive souvent de souhaiter interdire à une application d'avoir plusieurs instances lancées.
Voici une petite classe qui lors du démarrage de l'application, s'assure qu'elle n'est pas déjà en cours d'exécution.
Elle utilise un objet mutex nommé, donc potentiellement visible par tous les autres processus.
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | using System.Threading; class SingleInstanceApp : IDisposable { // Mutex Mutex _siMutex; bool _siMutexOwned; // Constructeur public SingleInstanceApp(string name) { _siMutex = new Mutex(false, name); _siMutexOwned = false; } // Application déjà lancée ? public bool IsRunning() { // Acquisition du mutex. // Si _siMutexOwned vaut true, l'application acquiert le mutex car il est "libre" // Sinon le mutex a déjà été acquis lors du lancement d'une instance précédente _siMutexOwned = _siMutex.WaitOne(0, true); return !(_siMutexOwned); } // Membre de IDisposable public void Dispose() { // Libération du mutex si il a été acquis if (_siMutexOwned) _siMutex.ReleaseMutex(); } } |
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 | static void Main() { // En utilisant using, app.Dispose() est appelée automatiquement // Merci CSharp ;-) using (SingleInstanceApp app = new SingleInstanceApp("{123456789 - ABCD - EFEG - XXXX}")) { if (app.IsRunning()) MessageBox.Show("Application déjà lancée"); else Application.Run(new Form1()); } } |
Si une application lambda en cours d'exécution crée un mutex ayant le même nom que celui de notre application, cette dernière ne pourra plus se lancer.
Elle se comportera comme si une autre instance de l'application était déjà en cours.
Il existe une technique pour l'éviter mais cela sort de notre sujet. Veuillez donc à choisir un nom assez compliqué pour votre mutex.
Lorsque l'application se lance, il suffit de récupérer le processus courant et ensuite de parcourir la liste des processus en cours d'exécution sur la machine. Si le nom du processus courant correspond au nom d'un processus lancé sur la machine, l'application est déjà lancée et on peut donc l'arrêter directement.
Tout cela sera possible grâce à la classe Process.
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | [STAThread] static void Main() { if (TestSiApplicationDejaLancee() == false) { // Première instance de l'application Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); } else { // L'application a déjà été lancée Application.Exit(); } } static bool TestSiApplicationDejaLancee() { // Récupération du processus courant Process currentProcess = Process.GetCurrentProcess(); // Parcours de la liste des processus de la machine foreach (Process p in Process.GetProcesses()) { // Test si le processus courant est bien différent du processus de la liste // et que les deux processus en question ont le même nom if (p.Id != currentProcess.Id && p.ProcessName.Equals(currentProcess.ProcessName) == true) return true; } return false; } |
La classe System.Random nous permet de générer des nombres aléatoires.
Il s'agit en fait de nombres pseudo-aléatoires, car la séquence générée dépend de l'initialisation.
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | private void Button1_Click(object sender, System.EventArgs e) { // Pour générer toujours la même séquence, // on passe la même valeur au constructeur. // Random rnd = new Random(100); // Initialisation par défaut basée sur le temps. // La séquence est différente à chaque fois. Random rnd = new Random(); // Génération de 15 nombres aléatoires compris entre 0 et 255 byte[] rndNumbers = new Byte[15]; rnd.NextBytes(rndNumbers); ListBox1.Items.Clear(); for (byte i = 0; i < 15; i++) // On peut aussi faire un modulo pour n'obtenir que // des nombres entre 0 et 100 par exemples if (rndNumbers[i] > 100) ListBox1.Items.Add(rndNumbers[i] % 100); else ListBox1.Items.Add(rndNumbers[i]); // Pour générer des nombres aléatoire de type Integer int i = rnd.Next(); int j = rnd.Next(500, 1000); // j sera compris entre 500 et 999 // Pour générer des nombre aléatoire de type Double // d sera compris entre 0,0 et 1,0. // Il suffit de combiner cet appel à celui de Next() // pour avoir des doubles supérieurs à 1,0 double d = rnd.NextDouble(); } |
Le plus simple est d'utiliser un fichier de ressources (.resx). Le fichier de ressources principal de l'assembly peut être créé et modifié à partir de la page de propriétés du projet, dans l'onglet Ressources.
Pour ajouter un fichier existant dans le fichier de ressources, ouvrez le fichier de ressources, cliquez « Ajouter une ressource », « Ajouter un fichier existant », et sélectionnez le fichier voulu. Il sera ensuite accessible dans le code via Properties.Ressources.NomDuFichierSansExtension.
On peut aussi utiliser un fichier en tant que ressource sans l'ajouter à un fichier .resx :
- ajouter le fichier au projet via Menu Projet / Ajouter un élément existant
- définir l'action de compilation comme « Ressource incorporée » dans les propriétés du fichier
Ensuite, pour utiliser la ressource dans le code (dans l'exemple c'est un fichier texte nommé fichier.txt) :
Code c# : | Sélectionner tout |
1 2 3 4 | string fileName = "fichier.txt"; Assembly assembly = Assembly.GetExecutingAssembly(); string resourceFileName = assembly.GetName().Name + "." + fileName; Stream stream = assembly.GetManifestResourceStream(resourceFileName); |
Avec la version 2 du Framework, il est apparu la classe StopWatch qui permet de mesurer un intervalle de temps avec grande précision :
Code c# : | Sélectionner tout |
1 2 3 4 5 6 7 8 9 10 11 | Stopwatch maMesureDeTemps = new Stopwatch(); // Démarrage de l'intervalle de temps maMesureDeTemps.Start(); // ... // Fin de l'intervalle de temps maMesureDeTemps.Stop(); Console.WriteLine("L'exécution du code a pris : {0}", maMesureDeTemps.Elapsed.ToString()); |
Proposer une nouvelle réponse sur la FAQ
Ce n'est pas l'endroit pour poser des questions, allez plutôt sur le forum de la rubrique pour çaLes sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2024 Developpez Developpez LLC. Tous droits réservés Developpez LLC. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents et images sans l'autorisation expresse de Developpez LLC. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.