Heim  >  Artikel  >  Backend-Entwicklung  >  Detaillierte Einführung in die Delegation und anonyme Delegation in C#

Detaillierte Einführung in die Delegation und anonyme Delegation in C#

黄舟
黄舟Original
2017-09-02 14:53:541548Durchsuche

Dieser Artikel stellt hauptsächlich die relevanten Informationen zur C#-Delegierung und zur anonymen Delegation im Detail vor. Er hat einen gewissen Referenzwert.

Ursprünglich wollte ich einen Artikel „Delegation“ „Die Vergangenheit“ schreiben und Present Life of Lambda Expressions“, aber nur der Delegationsteil wurde viel geschrieben, daher werde ich den Inhalt über Lambda-Ausdrücke trennen und später schreiben.

Ich weiß nicht, wer Lambda-Ausdrücke erfunden hat. Ich erinnere mich nur daran, dass ich zum ersten Mal mit Lambda-Ausdrücken in Berührung gekommen bin, als ich VS2008 verwendet habe. Nehmen wir also zunächst an, dass sie von Microsoft erfunden wurden.

Lambda-Ausdrücke sind immer beliebter geworden, seit ich mit ihnen in Berührung gekommen bin. Sie wurden in Java 8 unterstützt, und Kotlin hat C# und F# ausgiebig plagiiert (hat C# Java nicht einst so behandelt?). eine Zeit). Tatsächlich verdeutlicht dies vollständig die Bedeutung von Lambda-Ausdrücken. Um Lambda zu verstehen, müssen Sie zunächst die Delegation verstehen.

Delegation:

Angenommen, wir möchten jetzt ein Programm entwickeln, das zwei ganze Zahlen verarbeitet (vorausgesetzt, die Additionsoperation wird zuerst verarbeitet)


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();
}

Wenn wir es nach einer Weile in eine Subtraktionsoperation umwandeln müssen:


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

Obwohl es eine sehr große Änderung gibt a+b zu a-b Winzig, aber es kann hier mehrere Änderungen geben (von der Subtraktion zur Division ...). Wenn es eine Änderung gibt, sollte die Änderung gekapselt werden. Hier können wir das Betriebsverhalten von a und b abstrahieren. Delegate


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

public Delegate int TwoNumberHandleMethodDelegate(int x, int y); Hier mit Delegate versehen, bedeutet dies, dass es sich um eine Delegate-Definition handelt. Wenn Sie den Delegaten entfernen und sich die Definition ansehen, werden Sie feststellen, dass es sich um eine abstrakte Methode ohne Methodenkörper handelt. Die Bedeutung der Delegation ist also: der Methodentyp mit derselben Signaturform wie die abstrakte Methode. Ein Delegate ist ein neuer Datentyp, den Sie definieren. Es ist derselbe Datentyp wie int und class. int stellt eine Ganzzahl dar, und jede Ganzzahl kann einer Variablen vom Typ int zugewiesen werden. TwoNumberHandleMethodDelegate stellt eine Methode dar, die zwei Parameter vom Typ int empfängt und ein Ergebnis vom Typ int zurückgibt vom Typ TwoNumberHandleMethodDelegate.

Auf diese Weise kann der Worker-Code wie folgt geändert werden:


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

Auf diese Weise lauten die Operationen von a und b gekapselt und alle Änderungen werden dem Aufrufer überlassen. Die Bedeutung hier: HandleTwoNumber verarbeitet zwei Ganzzahlen a und b. Die spezifische Verarbeitung wird durch handle implementiert. An dieser Stelle fragen Sie sich vielleicht, wie man diese Methode aufruft. Der Aufruf lautet wie folgt:


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));
 }

Gemäß dem obigen Programm ist der Hauptcodeblock der Anrufer des Arbeiters. Als Anrufer sollten Sie am besten wissen, was Sie möchten, dass der Arbeiter arbeitet. Als Arbeiter des Angerufenen muss er daher nur den vom Aufrufer Main angegebenen ab-Parameter empfangen und die von Main angepasste Algorithmusmethode ausführen und dann den Algorithmus gemäß dem Algorithmus ausführen und das Ergebnis zurückgeben. Obwohl der obige Code einfach ist, ist seine Bedeutung weitreichend. Mit zunehmender Programmierzeit wird Ihr Verständnis meiner Meinung nach tiefer.

Zusätzlich zur Standardmethode zum Zuweisen von Werten zu Delegatenvariablen kann dies auch vereinfacht werden:


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);

Der Compiler führt eine automatische Überprüfung durch ob Add der TwoNumberHandleMethodDelegate-Definition entspricht, die eine direkte Zuweisung des Methodennamens zur Delegatvariablen ermöglicht, wenn sie konform ist.

Anonymer Delegat

Anhand des obigen Beispielcodes können wir leicht feststellen, dass der Methodenvariablen TwoNumberHandleMethodDelegate Add(Sub) zugewiesen ist, sodass beim Aufruf von method(... ) entspricht dem Aufruf von Add(.....). Auf diese Weise kann davon ausgegangen werden, dass die Methode

völlig äquivalent zu Add ist. Kann der Definitionsinhalt von Add direkt der Methodenvariablen zugewiesen werden? Die Antwort ist ja:


static void Main(string[] args)
    {

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

Aber eine starre Anwendung wie oben funktioniert nicht, Sie müssen noch Änderungen vornehmen. Die Änderung ist: Da sich der aktuelle Code in der Main-Methode befindet, wird der Zugriffsmodifikator entfernt und gleichzeitig sollte auch static entfernt werden. Der Compiler weiß, dass Sie der Methode einen Wert zuweisen möchten Die Zuweisung muss dem Rückgabetyp von int entsprechen, sodass zu diesem Zeitpunkt nicht alle Int-Methoden entfernt werden müssen, da die Methode nach der Zuweisung äquivalent zu Add ist und nachfolgende Aufrufe über die Methodenvariable abgeschlossen werden können und nicht alle Add-Methodennamen erforderlich sind entfernt werden. Der Code lautet also wie folgt:


static void Main(string[] args)
    {

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

Nach der obigen Änderung wurde der Inhalt stark vereinfacht, aber was ist das rechte Ende von = in der Methodenzuweisung? ? Zu diesem Zeitpunkt kann der Compiler nicht korrekt erkennen, dass es sich um eine Methode handelt, da die Definition der Methode Folgendes enthalten muss: Zugriffsmodifikator, Rückgabetyp, Methodenname, Parameterliste und Methodenkörper. Obwohl Sie tief in Ihrem Herzen wissen, dass dies eine vereinfachte Methode ist, versteht der Compiler Ihre Meinung nicht ... Das spielt jedoch keine Rolle, solange wir dem Compiler mitteilen, dass es sich bei dem, was folgt, um eine vereinfachte Methode handelt.


static void Main(string[] args)
    {

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

Wie zu erwarten, weiß der Compiler jetzt = die rechte Seite ist Ihre vereinfachte Methode; ok, jetzt kann sie normal zugewiesen und verwendet werden.

Anhand der obigen Definition stellen wir fest, dass die mit Delegate gekennzeichnete vereinfachte Methode keinen festen Namen wie Add/Sub hat. Deshalb nennen wir diese Methode anonyme Delegation (ich bin es gewohnt, sie anonyme Methode zu nennen).

Möglicherweise stellen Sie auch fest, dass der anonyme Delegat der lokalen Variablenmethode im Hauptcodeblock zugewiesen wird. Wenn der Gültigkeitsbereich der Methode überschritten wird, kann die Methode daher nie aufgerufen werden . Dies führt zu den häufigsten Verwendungen von anonymen Methoden, anonymen Delegaten und anonymen Funktionen, die dazu dienen, Funktionscode zu definieren, der nur einmal verwendet werden muss.

Das obige ist der detaillierte Inhalt vonDetaillierte Einführung in die Delegation und anonyme Delegation in C#. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn