Partager via


Tutoriel : Explorer des idées à l’aide d’instructions de niveau supérieur pour générer du code à mesure que vous apprenez

Dans ce tutoriel, vous allez apprendre à :

  • Découvrez les règles régissant votre utilisation de déclarations supérieures.
  • Utilisez des instructions de niveau supérieur pour explorer les algorithmes.
  • Refactorisez des explorations en composants réutilisables.

Conditions préalables

Vous devez configurer votre ordinateur pour exécuter .NET 6 ou version ultérieure. Le compilateur C# est disponible à partir de Visual Studio 2022 ou sdk .NET.

Ce tutoriel suppose que vous connaissez C# et .NET, notamment Visual Studio ou l’interface CLI .NET.

Commencer à explorer

Les instructions de niveau supérieur vous permettent d’éviter la cérémonie supplémentaire requise en plaçant le point d’entrée de votre programme dans une méthode statique dans une classe. Le point de départ classique d’une nouvelle application console ressemble au code suivant :

using System;

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

Le code précédent est le résultat de l’exécution de la commande dotnet new console et de la création d’une application console. Ces 11 lignes ne contiennent qu’une seule ligne de code exécutable. Vous pouvez simplifier ce programme avec la nouvelle fonctionnalité d’instructions de niveau supérieur. Cela vous permet de supprimer toutes les lignes sauf deux dans ce programme :

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

Important

Les modèles C# pour .NET 6 utilisent instructions de niveau supérieur. Votre application ne correspond peut-être pas au code de cet article, si vous avez déjà effectué la mise à niveau vers .NET 6. Pour plus d’informations, consultez l’articleLes nouveaux modèles C# génèrent des instructions de niveau supérieur.

Le Kit de développement logiciel (SDK) .NET 6 ajoute également un ensemble de directives de implicitesglobal using pour les projets qui utilisent les kits SDK suivants :

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker

Ces directives global using implicites incluent les espaces de noms les plus courants pour le type de projet.

Pour plus d’informations, consultez l’article sur les directives d’utilisation implicite

Cette fonctionnalité simplifie ce qui est nécessaire pour commencer à explorer de nouvelles idées. Vous pouvez utiliser des instructions de niveau supérieur pour les scénarios de script ou pour explorer. Une fois que vous avez les principes de base, vous pouvez commencer à refactoriser le code et créer des méthodes, des classes ou d’autres assemblys pour les composants réutilisables que vous avez créés. Les instructions de niveau supérieur permettent une expérimentation rapide et des tutoriels pour débutants. Ils fournissent également une voie fluide de l’expérimentation à des programmes complets.

Les instructions de niveau supérieur sont exécutées dans l’ordre dans lequel elles apparaissent dans le fichier. Les instructions de niveau supérieur ne peuvent être utilisées que dans un fichier source dans votre application. Le compilateur génère une erreur si vous les utilisez dans plusieurs fichiers.

Créer une machine de réponse .NET magique

Pour ce tutoriel, nous allons créer une application console qui répond à une question « oui » ou « non » avec une réponse aléatoire. Vous générez les fonctionnalités étape par étape. Vous pouvez vous concentrer sur votre tâche plutôt que sur la cérémonie nécessaire à la structure d’un programme classique. Ensuite, une fois que vous êtes satisfait de la fonctionnalité, vous pouvez refactoriser l’application comme vous le voyez.

Un bon point de départ consiste à réécrire la question dans la console. Vous pouvez commencer par écrire le code suivant :

Console.WriteLine(args);

Vous ne déclarez pas de variable args. Pour le fichier source unique qui contient vos instructions de niveau supérieur, le compilateur reconnaît args pour signifier les arguments de ligne de commande. Le type d'args est un string[], comme dans tous les programmes C#.

Vous pouvez tester votre code en exécutant la commande dotnet run suivante :

dotnet run -- Should I use top level statements in all my programs?

Les arguments après la -- sur la ligne de commande sont passés au programme. Vous pouvez voir le type de la variable args, car elle est imprimée dans la console :

System.String[]

Pour écrire la question dans la console, vous devez énumérer les arguments et les séparer d’un espace. Remplacez l’appel WriteLine par le code suivant :

Console.WriteLine();
foreach(var s in args)
{
    Console.Write(s);
    Console.Write(' ');
}
Console.WriteLine();

À présent, lorsque vous exécutez le programme, il affiche correctement la question sous la forme d’une chaîne d’arguments.

Répondre avec une réponse aléatoire

Après avoir fait écho à la question, vous pouvez ajouter le code pour générer la réponse aléatoire. Commencez par ajouter un tableau de réponses possibles :

string[] answers =
[
    "It is certain.",       "Reply hazy, try again.",     "Don’t count on it.",
    "It is decidedly so.",  "Ask again later.",           "My reply is no.",
    "Without a doubt.",     "Better not tell you now.",   "My sources say no.",
    "Yes – definitely.",    "Cannot predict now.",        "Outlook not so good.",
    "You may rely on it.",  "Concentrate and ask again.", "Very doubtful.",
    "As I see it, yes.",
    "Most likely.",
    "Outlook good.",
    "Yes.",
    "Signs point to yes.",
];

Ce tableau contient 10 réponses affirmatives, cinq qui sont non engagées, et cinq qui sont négatives. Ensuite, ajoutez le code suivant pour générer et afficher une réponse aléatoire à partir du tableau :

var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);

Vous pouvez réexécuter l’application pour afficher les résultats. Vous devriez voir quelque chose comme la sortie suivante :

dotnet run -- Should I use top level statements in all my programs?

Should I use top level statements in all my programs?
Better not tell you now.

Ce code répond aux questions, mais nous allons ajouter une autre fonctionnalité. Vous souhaitez que votre application de question simule la réflexion sur la réponse. Pour ce faire, vous pouvez ajouter un peu d’animation ASCII, et faire une pause pendant que vous travaillez. Ajoutez le code suivant après la ligne qui fait écho à la question :

for (int i = 0; i < 20; i++)
{
    Console.Write("| -");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("/ \\");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("- |");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("\\ /");
    await Task.Delay(50);
    Console.Write("\b\b\b");
}
Console.WriteLine();

Vous devez également ajouter une directive using en haut du fichier source :

using System.Threading.Tasks;

Les directives using doivent être antérieures à d’autres instructions du fichier. Sinon, il s’agit d’une erreur du compilateur. Vous pouvez réexécuter le programme et voir l’animation. Cela améliore l'expérience. Expérimentez la longueur du délai pour correspondre à votre goût.

Le code précédent crée un ensemble de lignes tournantes séparées par un espace. L’ajout du mot clé await indique au compilateur de générer le point d’entrée du programme en tant que méthode qui a le modificateur async et retourne un System.Threading.Tasks.Task. Ce programme ne retourne pas de valeur. Par conséquent, le point d’entrée du programme retourne un Task. Si votre programme retourne une valeur entière, vous devez ajouter une instruction return à la fin de vos instructions de niveau supérieur. Cette instruction return spécifie la valeur entière à retourner. Si vos instructions de niveau supérieur incluent une expression await, le type de retour devient System.Threading.Tasks.Task<TResult>.

Refactorisation pour le futur

Votre programme doit ressembler au code suivant :

Console.WriteLine();
foreach(var s in args)
{
    Console.Write(s);
    Console.Write(' ');
}
Console.WriteLine();

for (int i = 0; i < 20; i++)
{
    Console.Write("| -");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("/ \\");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("- |");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("\\ /");
    await Task.Delay(50);
    Console.Write("\b\b\b");
}
Console.WriteLine();

string[] answers =
[
    "It is certain.",       "Reply hazy, try again.",     "Don't count on it.",
    "It is decidedly so.",  "Ask again later.",           "My reply is no.",
    "Without a doubt.",     "Better not tell you now.",   "My sources say no.",
    "Yes – definitely.",    "Cannot predict now.",        "Outlook not so good.",
    "You may rely on it.",  "Concentrate and ask again.", "Very doubtful.",
    "As I see it, yes.",
    "Most likely.",
    "Outlook good.",
    "Yes.",
    "Signs point to yes.",
];

var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);

Le code précédent est raisonnable. Ça marche. Mais ce n’est pas réutilisable. Maintenant que vous disposez de l’application, il est temps d’extraire des composants réutilisables.

L’un des candidats est le code qui affiche l’animation d’attente. Cet extrait de code peut devenir une méthode :

Vous pouvez commencer par créer une fonction locale dans votre fichier. Remplacez l’animation actuelle par le code suivant :

await ShowConsoleAnimation();

static async Task ShowConsoleAnimation()
{
    for (int i = 0; i < 20; i++)
    {
        Console.Write("| -");
        await Task.Delay(50);
        Console.Write("\b\b\b");
        Console.Write("/ \\");
        await Task.Delay(50);
        Console.Write("\b\b\b");
        Console.Write("- |");
        await Task.Delay(50);
        Console.Write("\b\b\b");
        Console.Write("\\ /");
        await Task.Delay(50);
        Console.Write("\b\b\b");
    }
    Console.WriteLine();
}

Le code précédent crée une fonction locale à l’intérieur de votre méthode principale. Ce code n’est toujours pas réutilisable. Extrayez donc ce code dans une classe. Créez un fichier nommé utilities.cs et ajoutez le code suivant :

namespace MyNamespace
{
    public static class Utilities
    {
        public static async Task ShowConsoleAnimation()
        {
            for (int i = 0; i < 20; i++)
            {
                Console.Write("| -");
                await Task.Delay(50);
                Console.Write("\b\b\b");
                Console.Write("/ \\");
                await Task.Delay(50);
                Console.Write("\b\b\b");
                Console.Write("- |");
                await Task.Delay(50);
                Console.Write("\b\b\b");
                Console.Write("\\ /");
                await Task.Delay(50);
                Console.Write("\b\b\b");
            }
            Console.WriteLine();
        }
    }
}

Un fichier qui possède des instructions de niveau supérieur peut également contenir des espaces de noms et des types à la fin du fichier, après les instructions de niveau supérieur. Toutefois, pour ce tutoriel, vous placez la méthode d’animation dans un fichier distinct pour le rendre plus facilement réutilisable.

Enfin, vous pouvez nettoyer le code d’animation pour éliminer certaines duplications en utilisant la boucle foreach pour itérer à travers un ensemble d’éléments d’animation définis dans le tableau animations.
La méthode ShowConsoleAnimation complète après refactorisation doit ressembler au code suivant :

public static async Task ShowConsoleAnimation()
{
    string[] animations = ["| -", "/ \\", "- |", "\\ /"];
    for (int i = 0; i < 20; i++)
    {
        foreach (string s in animations)
        {
            Console.Write(s);
            await Task.Delay(50);
            Console.Write("\b\b\b");
        }
    }
    Console.WriteLine();
}

Vous disposez maintenant d’une application complète et vous avez refactorisé les parties réutilisables pour une utilisation ultérieure. Vous pouvez appeler la nouvelle méthode utilitaire à partir de vos instructions de niveau supérieur, comme indiqué dans la version finale du programme principal :

using MyNamespace;

Console.WriteLine();
foreach(var s in args)
{
    Console.Write(s);
    Console.Write(' ');
}
Console.WriteLine();

await Utilities.ShowConsoleAnimation();

string[] answers =
[
    "It is certain.",       "Reply hazy, try again.",     "Don’t count on it.",
    "It is decidedly so.",  "Ask again later.",           "My reply is no.",
    "Without a doubt.",     "Better not tell you now.",   "My sources say no.",
    "Yes – definitely.",    "Cannot predict now.",        "Outlook not so good.",
    "You may rely on it.",  "Concentrate and ask again.", "Very doubtful.",
    "As I see it, yes.",
    "Most likely.",
    "Outlook good.",
    "Yes.",
    "Signs point to yes.",
];

var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);

L’exemple précédent ajoute l’appel à Utilities.ShowConsoleAnimationet ajoute une autre directive using.

Résumé

Les instructions de niveau supérieur facilitent la création de programmes simples à utiliser pour explorer de nouveaux algorithmes. Vous pouvez expérimenter des algorithmes en essayant différents extraits de code. Une fois que vous avez appris ce qui fonctionne, vous pouvez refactoriser le code pour être plus gérable.

Les instructions de niveau supérieur simplifient les programmes basés sur des applications console. Ces applications incluent des fonctions Azure, des actions GitHub et d’autres utilitaires de petite taille. Pour plus d’informations, consultez Instructions de niveau supérieur (Guide de programmation C#).