Maison >développement back-end >Tutoriel C#.Net >Introduction détaillée à la délégation et à la délégation anonyme en C#

Introduction détaillée à la délégation et à la délégation anonyme en C#

黄舟
黄舟original
2017-09-02 14:53:541580parcourir

Cet article présente principalement en détail les informations pertinentes sur la délégation C# et la délégation anonyme. Il a une certaine valeur de référence. Les amis intéressés peuvent s'y référer

À l'origine, je voulais écrire un article "Délégation" "Le passé. et la vie actuelle des expressions Lambda", mais seule la partie délégation a été beaucoup écrite, je vais donc séparer le contenu sur les expressions Lambda et l'écrire plus tard.

Je ne sais pas qui a inventé les expressions Lambda. Je me souviens juste que la première fois que je suis entré en contact avec les expressions Lambda, c'était lors de l'utilisation de VS2008, alors pensons d'abord qu'elles ont été inventées par Microsoft.

Les expressions Lambda sont devenues de plus en plus populaires depuis que je suis entré en contact avec elles. Elles ont commencé à être prises en charge dans Java 8, et Kotlin a largement plagié C# et F# (C# n'a-t-il pas traité Java comme ça autrefois). une fois) . En fait, cela illustre pleinement l’importance des expressions Lambda. Pour comprendre Lambda, vous devez d'abord comprendre la délégation.

Délégation :

Supposons maintenant que nous voulions développer un programme qui traite deux entiers (en supposant que l'opération d'addition soit traitée en premier)


public class Worker
    {
      /// <summary>
      /// 处理两个数
      /// </summary>
      /// <param name="a"></param>
      /// <param name="b"></param>
      /// <returns></returns>
      public int HandleTwoNumber(int a,int b)
      {
        return a + b;
      }
    }
static void Main(string[] args)
    {
      int a = int.Parse(Console.ReadLine());
      int b = int.Parse(Console.ReadLine());

      Worker worker = new Worker();
      int result = worker.HandleTwoNumber(a, b);
      Console.WriteLine(String.Format("Result:{0}", result));

      string p = Console.ReadLine();
}

Si au bout d'un moment, nous devons le changer en une opération de soustraction :


public class Worker
    {
      public int HandleTwoNumber(int a,int b)
      {
        return a - b;
      }
    }

Bien qu'il y ait un très gros changement par rapport a+b en a-b Minuscule, mais il peut y avoir plusieurs changements ici (de la soustraction à la division...). S'il y a un changement, le changement doit être encapsulé. Ici, nous pouvons faire abstraction du comportement opérationnel de a et b. Quelle abstraction devons-nous utiliser ? Delegate


public class Worker
    {
      public delegate int TwoNumberHandleMethodDelegate(int x, int y);
      public int HandleTwoNumber(int a,int b)
      {
        return a + b;
      }
    }

public délégué int TwoNumberHandleMethodDelegate(int x, int y); Annoté avec délégué ici, cela indique qu'il s'agit d'une définition de délégué. Si vous supprimez le délégué et regardez la définition, vous constaterez qu'il s'agit d'une méthode abstraite sans corps de méthode. La signification de la délégation est donc : le type de méthode avec la même forme de signature que la méthode abstraite. Un délégué est un nouveau type de données que vous définissez. C'est le même type de données que int et class. int représente un entier, et n'importe quel entier peut être affecté à une variable de type int ; TwoNumberHandleMethodDelegate représente une méthode qui reçoit deux paramètres de type int et renvoie un résultat de type int. Par conséquent, les méthodes qui répondent aux exigences ci-dessus peuvent être affectées à des variables. du type TwoNumberHandleMethodDelegate.

De cette manière, le code Worker peut être modifié comme :


public class Worker
    {
      public delegate int TwoNumberHandleMethodDelegate(int x, int y);
      public int HandleTwoNumber(int a, int b, TwoNumberHandleMethodDelegate handle)
      {
        return handle(a, b);
      }
    }

De cette manière, les opérations de a et b sont encapsulé, et toutes les modifications sont laissées à l'appelant. La signification ici : HandleTwoNumber traite deux entiers a et b. Le traitement spécifique est implémenté par handle. À ce stade, vous vous demandez peut-être comment appeler cette méthode ? L'appel est le suivant :


private static int Add(int a, int b)
    {
      return a + b;
    }

    private static int Sub(int a, int b)
    {
      return a - b;
    }

    static void Main(string[] args)
    {
      int a = int.Parse(Console.ReadLine());
      int b = int.Parse(Console.ReadLine());
      Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);
      Worker worker = new Worker();
      int result = worker.HandleTwoNumber(10, 10,method);
       //int result = worker.HandleTwoNumber(10, 10, Sub);//简化版
      Console.WriteLine(String.Format("Result:{0}", result));
 }

Selon le programme ci-dessus, le bloc de code principal est l'appelant du travailleur. En tant qu'appelant, vous devriez mieux savoir quoi. vous voulez que le travailleur fasse le travail. Par conséquent, en tant que travailleur de l'appelé, il lui suffit de recevoir le paramètre ab donné par l'appelant Main et d'exécuter la méthode d'algorithme personnalisée par Main, puis d'exécuter l'algorithme selon l'algorithme et de renvoyer le résultat. Bien que le code ci-dessus soit simple, sa signification est considérable. À mesure que votre temps de programmation augmente, je pense que votre compréhension deviendra plus profonde.

En plus de la manière standard d'attribuer des valeurs aux variables déléguées, elle peut également être simplifiée :


Worker.TwoNumberHandleMethodDelegate method = new Worker.TwoNumberHandleMethodDelegate(Add);
      Worker worker = new Worker();
      int result = worker.HandleTwoNumber(10, 10,method);
//可简化为
// int result = worker.HandleTwoNumber(10, 10,Add);

Le compilateur vérifiera automatiquement si Add est conforme à la définition TwoNumberHandleMethodDelegate, qui permet l'attribution directe du nom de méthode à la variable déléguée si elle est remplie.

Délégué anonyme

Grâce à l'exemple de code ci-dessus, nous pouvons facilement constater que la variable de méthode TwoNumberHandleMethodDelegate est affectée à Add(Sub), donc lors de l'appel de méthode(... ) équivaut à appeler Add(.....). De cette façon, on peut considérer que la

méthode est tout à fait équivalente à Add. Puisqu'elles sont équivalentes, le contenu de la définition de Add peut-il être directement affecté à la variable de méthode ? La réponse est oui :


static void Main(string[] args)
    {

      Worker.TwoNumberHandleMethodDelegate method =private static int Add(int a, int b)
    {
      return a + b;
    };
}

Mais une application rigide comme celle ci-dessus ne fonctionnera pas, vous devez quand même apporter des modifications. La modification est la suivante : comme le code actuel est dans la méthode Main, le modificateur d'accès est supprimé et static doit également être supprimé en même temps, le compilateur sait que vous souhaitez attribuer une valeur à la méthode, donc la valeur à ; être assigné doit répondre au type de retour de int, donc tout Int n'est pas nécessaire à supprimer pour le moment car après l'affectation, la méthode est équivalente à Add, et les appels suivants peuvent être effectués via la variable de méthode, et tous les noms de méthode Add n'ont pas besoin à supprimer. Le code devient donc le suivant :


static void Main(string[] args)
    {

      Worker.TwoNumberHandleMethodDelegate method =  (int a, int b)
    {
      return a + b;
    };
}

Après la modification ci-dessus, le contenu a été beaucoup simplifié, mais quelle est la bonne fin de = dans l'affectation de la méthode ? Pour le moment, le compilateur ne peut pas identifier correctement qu'il s'agit d'une méthode, car la définition de la méthode doit inclure : le modificateur d'accès, le type de retour, le nom de la méthode, la liste des paramètres et le corps de la méthode. Même si vous savez dans votre cœur qu'il s'agit d'une méthode simplifiée, le compilateur ne comprend pas votre esprit..., cela n'a pas d'importance tant que nous disons au compilateur que ce qui suit est une méthode simplifiée.


static void Main(string[] args)
    {

      Worker.TwoNumberHandleMethodDelegate method =  delegate(int a, int b)
    {
      return a + b;
    };
}

Comme vous vous en doutez, le compilateur sait maintenant = le côté droit est votre méthode simplifiée ok, maintenant elle peut être assignée et utilisée normalement.

Grâce à la définition ci-dessus, nous constatons que la méthode simplifiée marquée par délégué n'a pas de nom fixe comme Add/Sub. C'est pourquoi nous appelons cette méthode délégation anonyme (j'ai l'habitude de l'appeler méthode anonyme).

Vous remarquerez peut-être également qu'une fois le délégué anonyme défini, il est affecté à la méthode de variable locale dans le bloc de code principal. Par conséquent, lorsque la portée de la méthode est dépassée, la méthode n'aura jamais la chance d'être appelée. . Cela conduit aux utilisations les plus courantes de méthodes anonymes, de délégués anonymes et de fonctions anonymes, qui consistent à définir un code fonctionnel qui ne doit être utilisé qu'une seule fois.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn