C# Délégué

En C#, un délégué est un pointeur de fonction sûr au niveau des types qui permet de passer des méthodes comme paramètres à d'autres méthodes.

Les délégués en C# sont similaires aux pointeurs de fonction en C ou C++.DéléguéEst une variable de type référence qui contient une référence à une méthode ; la référence peut être modifiée au moment de l'exécution.

Les délégués sont très courants en C# et sont utilisés pour la gestion d'événements, les fonctions de rappel, LINQ et d'autres opérations.

Tous les délégués dérivent de laSystem.Delegateclasse.

Déclaration d'un délégué

Un délégué est un type de référence qui définit une signature de méthode et peut être utilisé pour stocker une méthode correspondant à cette signature. Via un délégué, vous pouvez appeler des méthodes dans d'autres classes.

La déclaration du délégué détermine quelles méthodes peuvent être référencées par le délégué. Un délégué peut pointer vers une méthode ayant la même signature.

La syntaxe pour déclarer un délégué est la suivante :

public delegate <return type> <delegate-name> <parameter list>

Description du format chinois :

public delegate 返回类型 委托名(参数类型 参数名, ...);

Par exemple, le code suivant définit un délégué qui accepte deux entiers et renvoie un entier :

public delegate int MathOperation(int x, int y);

Le délégué dans l'exemple suivant peut être utilisé pour référencer toute méthode qui possède un seulstringune méthode avec paramètres et renvoie unintVariables de type.

public delegate int MyDelegate (string s);

Instancier un délégué (Delegate)

Une fois qu'un type délégué est déclaré, un objet délégué doit être créé à l'aide du mot clénew, et il est associé à une méthode spécifique. Lors de la création d'un délégué, l'argument passé à l'instructionnewest écrit comme un appel de méthode, mais sans les paramètres. Par exemple :

public delegate void printString(string s);
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);

L'exemple suivant montre la déclaration, l'instanciation et l'utilisation d'un délégué, qui peut être utilisé pour référencer une méthode qui prend un paramètre entier et renvoie une valeur entière.

Exemple

using System;

delegate int NumberChanger(int n);
namespace DelegateAppl
{
   class TestDelegate
   {
      static int num = 10;
      public static int AddNum(int p)
      {
         num += p;
         return num;
      }

      public static int MultNum(int q)
      {
         num *= q;
         return num;
      }
      public static int getNum()
      {
         return num;
      }

      static void Main(string[] args)
      {
         // Créer une instance de délégué
         NumberChanger nc1 = new NumberChanger(AddNum);
         NumberChanger nc2 = new NumberChanger(MultNum);
         // Utiliser un objet délégué pour appeler une méthode
         nc1(25);
         Console.WriteLine("Valeur de Num : {0}", getNum());
         nc2(5);
         Console.WriteLine("Valeur de Num : {0}", getNum());
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant :

Value of Num: 35
Value of Num: 175

Multidiffusion d'un délégué

Les objets délégués peuvent être utilisés+et sont combinés à l'aide de l'opérateur.

Un délégué combiné appelle les deux délégués qu'il combine ; seuls les délégués du même type peuvent être combinés.

-L'opérateur peut être utilisé pour supprimer un délégué composant d'un délégué combiné.

En utilisant cette fonctionnalité utile des délégués, vous pouvez créer une liste d'appel de méthodes à appeler lorsque le délégué est appelé. C'est ce qu'on appelle lamultidiffusion (multicasting)d'un délégué, également appelée multicast.

Le programme suivant illustre la multidiffusion de délégués :

Exemple

using System;

delegate int NumberChanger(int n);
namespace DelegateAppl
{
   class TestDelegate
   {
      static int num = 10;
      public static int AddNum(int p)
      {
         num += p;
         return num;
      }

      public static int MultNum(int q)
      {
         num *= q;
         return num;
      }
      public static int getNum()
      {
         return num;
      }

      static void Main(string[] args)
      {
         // Créer une instance de délégué
         NumberChanger nc;
         NumberChanger nc1 = new NumberChanger(AddNum);
         NumberChanger nc2 = new NumberChanger(MultNum);
         nc = nc1;
         nc += nc2;
         // Invoquer la multidiffusion
         nc(5);
         Console.WriteLine("Valeur de Num : {0}", getNum());
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant :

Value of Num: 75

Le but d'un délégué

L'exemple suivant illustre l'utilisation des délégués. Le déléguéprintStringpeut être utilisé pour référencer une méthode qui prend une chaîne en entrée et ne retourne rien.

Nous utilisons ce délégué pour appeler deux méthodes : la première affiche la chaîne dans la console, et la seconde affiche la chaîne dans un fichier :

Exemple

using System;
using System.IO;

namespace DelegateAppl
{
   class PrintString
   {
      static FileStream fs;
      static StreamWriter sw;
      // Déclaration de délégué
      public delegate void printString(string s);

      // Cette méthode affiche dans la console
      public static void WriteToScreen(string str)
      {
         Console.WriteLine("La chaîne est : {0}", str);
      }
      // Cette méthode écrit dans un fichier
      public static void WriteToFile(string s)
      {
         fs = new FileStream("c:\\message.txt", FileMode.Append, FileAccess.Write);
         sw = new StreamWriter(fs);
         sw.WriteLine(s);
         sw.Flush();
         sw.Close();
         fs.Close();
      }
      // Cette méthode prend un délégué comme paramètre et l'utilise pour appeler une méthode
      public static void sendString(printString ps)
      {
         ps("Hello World");
      }
      static void Main(string[] args)
      {
         printString ps1 = new printString(WriteToScreen);
         printString ps2 = new printString(WriteToFile);
         sendString(ps1);
         sendString(ps2);
         Console.ReadKey();
      }
   }
}

Lorsque le code ci-dessus est compilé et exécuté, il produit le résultat suivant :

The String is: Hello World

Supprimer le délégué

Si vous n'avez plus besoin d'une méthode, vous pouvez utiliser l'-=opérateur pour supprimer la méthode de la chaîne de délégués.

Exemple

public class Program
{
    public delegate void PrintMessage(string message);

    public static void PrintUpperCase(string message)
    {
        Console.WriteLine(message.ToUpper());
    }

    public static void PrintLowerCase(string message)
    {
        Console.WriteLine(message.ToLower());
    }

    public static void Main()
    {
        PrintMessage print = PrintUpperCase;
        print += PrintLowerCase;

        // Supprimer la méthode PrintLowerCase
        print -= PrintLowerCase;

        // Appel du délégué (appelle uniquement PrintUpperCase)
        print("Hello, C#");  // Sortie : HELLO, C#
    }
}

Délégués et événements

Les délégués sont souvent utilisés avec des événements. Un événement est un type spécial de délégué utilisé pour le mécanisme de publication/abonnement.

En C#, un événement est essentiellement un type qui encapsule un délégué, et il est utilisé pour répondre à certaines opérations dans le programme.

Exemple

public class Button
{
    // Définir un événement
    public event EventHandler Click;

    // Méthode pour déclencher un événement
    public void OnClick()
    {
        if (Click != null)
        {
            Click(this, EventArgs.Empty);  // Déclencher l'événement
        }
    }
}

public class Program
{
    public static void Main()
    {
        Button button = new Button();
       
        // S'abonner à l'événement
        button.Click += Button_Click;

        // Déclencher l'événement
        button.OnClick();  // Sortie "Button clicked!"
    }

    private static void Button_Click(object sender, EventArgs e)
    {
        Console.WriteLine("Bouton cliqué !");
    }
}

Types de délégués

C# fournit plusieurs types de délégués courants :

1、Action

Action: Représente une méthode qui ne renvoie pas de valeur. Elle peut accepter jusqu’à 16 paramètres.

Action<string> printMessage = Console.WriteLine;
printMessage("Hello");

2、Func

Func: Représente une méthode qui a une valeur de retour. Elle accepte jusqu’à 16 paramètres ; le premier paramètre est le paramètre d’entrée, et le dernier paramètre est le type de retour.

Func<int, int, int> add = (x, y) => x + y;
Console.WriteLine(add(3, 4));  // 输出 7

3、Predicate

Predicate: Représente une méthode qui renvoie une valeur bool, généralement utilisée pour des vérifications conditionnelles.

Predicate<int> isEven = x => x % 2 == 0;
Console.WriteLine(isEven(4));  // 输出 True

Remarques sur les délégués

Sécurité de type :Les délégués sont sûrs au niveau du type, ce qui signifie que seules les méthodes dont la signature correspond peuvent être affectées à un délégué.

Méthodes anonymes et expressions lambda : vous pouvez utiliser des méthodes anonymes ou des expressions lambda pour créer des instances de délégué, ce qui simplifie le code.

Func<int, int, int> add = (x, y) => x + y;
Console.WriteLine(add(5, 3));  // 输出 8

Appel asynchrone : vous pouvez utiliser des délégués avec les méthodes BeginInvoke et EndInvoke pour effectuer des appels asynchrones.

Les délégués sont une fonctionnalité très puissante et flexible de C# qui peut aider à mettre en œuvre la programmation événementielle, les mécanismes de rappel et les styles de programmation fonctionnelle. Ils offrent non seulement la possibilité de réutiliser du code, mais améliorent également la modularité des programmes. Comprendre et maîtriser l’utilisation des délégués est très important pour la programmation C#.

autres extensions