Dot.Blog

C#, XAML, WinUI, WPF, Android, MAUI, IoT, IA, ChatGPT, Prompt Engineering

C# 9.0+ : instructions de niveau supérieur. Où est la méthode Main ?

C# 9.0 introduit de nombreuses nouvelles fonctionnalités de langage dont les déclarations de niveau supérieur qui peuvent troubler notamment les adeptes de MAUI !

Une simplification qui cache du code

Je me suis aperçu que je n'avais pas encore vraiment abordé cet aspect qui peut être troublant dans MAUI et qu'il était temps de réparer cet oubli. J'ai oublié que certains pourraient être déconcertés car ce n'est pas du MAUI mais une spécificité de C#9. Mais ce n'est pas grave. Réglons ce point tout de suite, mieux vaut tard que jamais !

Lorsque vous créez une nouvelle application console avec C# (cela reste vrai pour une App Maui), vous obtenez beaucoup de code passe-partout. Ci-dessous, vous voyez le code d'une nouvelle application avec le nom Enaxos.ConsoleApp .

using System;
namespace Enaxos.ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

Si vous débutez en C#, ce programme vous confrontera à de nombreux concepts :

  • utiliser des instructions
  • espaces de noms
  • blocs { }
  • Des classes
  • méthodes statiques
  • type de retour void
  • paramètres de tableau
  • Instruction Console.WriteLine

Déjà dans les versions antérieures de C# et .NET, l'espace de noms était facultatif. De plus, le paramètres "args" de la méthode Main est facultatif. Vous pourriez écrire le programme comme ceci sans le bloc namespace et sans le paramètre args :

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


Cela signifie que, dans notre liste, vous pouvez supprimer les espaces de noms et les paramètres de tableau :

  • utiliser des instructions
  • espaces de noms
  • blocs { }
  • Des classes
  • méthodes statiques
  • type de retour void
  • paramètres de tableau
  • Instruction Console.WriteLine

C# 9.0, qui vient avec .NET 5, fait passer tout cela au niveau au-dessus en autorisant les programmes dits de niveau supérieur. Cela signifie que vous pouvez écrire des instructions directement au niveau supérieur d'un fichier. Il n'est pas nécessaire de définir une classe et une méthode Main statique. Le code ci-dessous montre une application Hello World Console écrite avec C# 9.0 :

using System;
Console.WriteLine("Hello World!");

Maintenant, lorsque vous regardez la liste des fonctionnalités que nous avons ici par rapport à l'application Console d'origine, cela ressemble à ci-dessous. Il ne reste que la directive using et l'instruction Console.WriteLine :


  • utiliser des instructions
  • espaces de noms
  • blocs { }
  • Des classes
  • méthodes statiques
  • type de retour void
  • paramètres de tableau
  • Instruction Console.WriteLine

Cela montre clairement que les programmes de niveau supérieur simples sont un moyen facile de démarrer avec C#. Les débutants n'ont pas à apprendre toutes les différentes fonctionnalités dès le début. Est-ce un bien ? Je n'en suis pas sûr. C'est certainement vendeur pur comparer avec d'autres langages mais ce n'est pas à mon sens un bon moyen de comprendre vraiment ce que l'on fait. Mais il semble que le choix n'existe pas, même dans MAUI. Alors autant comprendre ce qu'il arrive. 

Lorsque vous utilisez .NET 5+ pour votre projet, la version par défaut est C# 9.0 en tant que version linguistique. Donc, assurez-vous simplement que votre projet s'exécute sur .NET 5+ en consultant le fichier .csproj et en vous assurant que le TargetFramework est défini sur net5.0 ou plus :

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>net5.0</TargetFramework>
  </PropertyGroup>
</Project>

Où est passée la méthode principale ?

Bonne question. Si vous avez travaillé avec .NET dans le passé, vous avez appris que l'entrée de chaque programme .NET est la méthode statique Main. Mais dans un programme de haut niveau, cette méthode Main n'existe pas, car nous n'avons que ce code  :

sing System;
Console.WriteLine("Hello World!");

Alors, où diable est notre méthode Main ? Regardons quel code est généré en utilisant l'outil classique disponible, le désassembleur de langage intermédiaire ou ILDASM court (il existe des alternatives plus puissantes comme ILSpy ou dnSpy , mais ILDASM fait le travail ici).

Si vous avez installé Visual Studio 2022, vous trouvez un dossier Visual Studio 2022 dans votre menu Démarrer. Dans ce dossier se trouve l'invite de commande du développeur pour Visual Studio 2022 :

Dans l'invite de commande du développeur, écrivez simplement ildasm et appuyez sur Entrée pour ouvrir le désassembleur de langage intermédiaire, comme vous pouvez le voir dans la capture d'écran ci-dessous. Notez que cela ne fonctionne que dans l'invite de commande du développeur et non dans une invite de commande normale, car l'invite de commande du développeur a le chemin défini en conséquence, de sorte que ILDASM.exe est trouvé. Avec VS 2022 cela fonctionne uniquement (chez moi) avec le Developer PowersShell l'invite de commande VS ne reconnait pas IlDasm.


Dans le désassembleur de langage intermédiaire, ouvrons le fichier .dll de notre application console qui utilise la fonctionnalité de programme de niveau supérieur de C # 9. Dans la capture d'écran ci-dessous, j'ai ouvert le fichier .dll. Vous pouvez voir qu'une classe $Program et une méthode $Main statique ont été générées en coulisses pour nous. Cela signifie qu'il existe toujours une méthode statique Main, mais elle est générée automatiquement si vous créez un programme de niveau supérieur dans lequel vous ne définissez pas explicitement cette méthode dans votre code.

Lorsque vous double-cliquez sur cette méthode $Main, vous pouvez voir le code de langue intermédiaire (IL). Vous pouvez le voir dans la capture d'écran ci-dessous. Le code vous montre que l'instruction de niveau supérieur est en fait ajoutée automatiquement. Cela signifie en d'autres termes que toutes vos instructions de niveau supérieur sont ajoutées à la méthode  $Main générée...


Arguments de la ligne de commande

Lorsque vous regardez la méthode $Main générée automatiquement dans la capture d'écran ci-dessus, vous pouvez voir que la méthode $Main a également le paramètre string[] conventionnel pour les arguments de ligne de commande. Comme les instructions de niveau supérieur que vous écrivez dans un fichier de programme de niveau supérieur sont placées dans cette méthode générée automatiquement, vous pouvez également accéder à ce paramètre string[], qui porte par convention le nom args. Vous pouvez donc écrire quelque chose comme ceci dans un programme de niveau supérieur pour afficher les arguments de la ligne de commande sur la console :

using System;
if (args?.Length > 0)
{
    foreach(var arg in args)
    {
        Console.WriteLine(arg);
    }
}

Conclusion

Le but n'était pas de vous faire un cours complet de C#9, pour en connaître toutes les subtilités comme des 8 versions précédentes et de celles qui le suivent, seule la documentation MS est présumée complète et à jour. D'autant que des efforts ont été faits pour présenter cette doc dans la langue du lecteur et que les explications sont agrémentées d'exemples simplifiant la compréhension.

Donc juste quelques mots pour expliquer ce "tour de passe-passe" qui peut en étonner plus un. Des instructions qui se baladent toutes seuls dans un fichier, sans classe, sans namespace... des champs comme args qui peuvent être utilisés sans être déclarés... 

Bref de la magie pure.

Entre nous, avec 15 ans de retard (ou plus) c'est déjà ce que Delphi, créé par le père de C#, faisait déjà avec un fichier qui contenait des variables "globales". En réalité une classe était générée en douce pour que tout soit propre, mais ça faisait raller les puristes de Pascal... Aujourd'hui nul doute que cela fera ronchonner les puristes de C#, mais le bougre de Anders Hejlsberg nous a déjà fait le coup, il y a longtemps chez Borland... Les vieux de la vieille sont moins surpris donc !

Stay Tuned !

Faites des heureux, partagez l'article !
blog comments powered by Disqus