English | 简体中文 | 繁體中文 | Русский язык | Français | Español | Português | Deutsch | 日本語 | 한국어 | Italiano | بالعربية

C# Delegat (Delegate)

Wie bringe ich eine Funktion als Parameter weiter? Wie behandelt C# Callback-Funktionen oder Event-Handler? Die Antwort ist-Delegat (Delegate). Der Delegate (Delegate) ist ein Referenzdatentypen-Variablen, die eine Referenz auf eine Methode speichern. Diese Referenz kann sich während der Laufzeit ändern.

Delegat istMethodesignatur definierenReferenzdatentypen. Sie können Delegat-Variablen wie andere Datentypen definieren, die auf alle Methoden verweisen können, die den Delegat-Signaturen entsprechen.

Arbeiten mit Delegaten beinhaltet drei Schritte:

  1. 声明委托

  2. Zielmethode festlegen

  3. Delegation aufrufen

Delegaten können mit dem Delegate-Schlüssel und der Funktionszeichenfolge erklärt werden, wie folgt.

  Delegatssyntax

[Zugriffsmodifikator] delegate [Rückgabetyp] [Delegatname]([Parameter])

Nachstehend wird ein Delegat namens MyDelegate erklärt.

public delegate void MyDelegate(string msg);

Oben haben wir einen MyDelegate mitvoidRückgabetyp und Zeichenfolgenparameter. Delegaten können sowohl außerhalb als auch innerhalb einer Klasse erklärt werden. Tatsächlich sollte sie außerhalb der Klasse erklärt werden.

Nach der Erklärung des Delegaten müssen wir die Zielmethode oder den Lambda-Ausdruck einstellen. Dies können wir durch Erstellen eines Delegaten-Objekts mit dem neuen Schlüssel und Übergeben des mit dem Delegaten übereinstimmenden Methodensignaturen erreichen.

public delegate void MyDelegate(string msg); // 声明委托
//Zielmethode festlegen
MyDelegate del = new MyDelegate(MethodA);
// oder
MyDelegate del = MethodA; 
// oder Lambda-Ausdrücke 
MyDelegate del = (string msg) => Console.WriteLine(msg);
// Zielmethode
static void MethodA(string message)
{
    Console.WriteLine(message);
}

Sie können das Zielmethoden direkt zuweisen, ohne ein Objekt der Delegation zu erstellen, z.B. MyDelegate del = MethodA.

Nachdem das Zielmethoden gesetzt wurde, kann die Invoke()-Methode oder der ()-Operator verwendet werden, um die Delegation aufzurufen.

del.Invoke("Hello World!");
//oder 
del("Hello World!");

Hier ist ein vollständiges Beispiel für die Delegation.

public delegate void MyDelegate(string msg); //声明委托
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del = ClassA.MethodA;
        del("Hello World");
        del = ClassB.MethodB;
        del("Hello World");
        del = (string msg) => Console.WriteLine("Aufgerufen Lambda-Ausdruck: ") + msg);
        del("Hello World");
    }
}
class ClassA
{
    static void MethodA(string message)
    {
        Console.WriteLine("Aufgerufen ClassA.MethodA() mit Parameter: ") + message);
    }
}
class ClassB
{
    static void MethodB(string message)
    {
        Console.WriteLine("Aufgerufen ClassB.MethodB() mit Parameter: ") + message);
    }
}

Das Diagramm zeigt die Delegation.

C# Delegation

Übergeben Sie Delegationen als Parameter

Methoden können Parameter vom Typ Delegation haben, wie folgt.

public delegate void MyDelegate(string msg); //声明委托
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del = ClassA.MethodA;
        InvokeDelegate(del);
        del = ClassB.MethodB;
        InvokeDelegate(del);
        del = (string msg) => Console.WriteLine("Aufgerufen Lambda-Ausdruck: ") + msg);
        InvokeDelegate(del);
    }
    static void InvokeDelegate(MyDelegate del) // Typparameter von MyDelegate
    {
        del("Hello World");
    }
}
class ClassA
{
    static void MethodA(string message)
    {
        Console.WriteLine("Aufgerufen ClassA.MethodA() mit Parameter: ") + message);
    }
}
class ClassB
{
    static void MethodB(string message)
    {
        Console.WriteLine("Aufgerufen ClassB.MethodB() mit Parameter: ") + message);
    }
}

In .NET sind die Typen Func und Action eingebaute generische Delegationen und sollten für die häufigsten Delegationen verwendet werden, anstatt neue benutzerdefinierte Delegationen zu erstellen.

Multicast-Delegation

Eine Delegation kann auf mehrere Methoden zeigen. Eine Delegation, die auf mehrere Methoden zeigt, wird als Multicast-Delegation bezeichnet.+"oder"+Der =-Operator fügt die Funktion zur Aufrufliste hinzu, während der-" und "-Das =-Operator löscht es.

public delegate void MyDelegate(string msg); //Erklärung der Delegation
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del1 = ClassA.MethodA;
        MyDelegate del2 = ClassB.MethodB;
        MyDelegate del = del1 + del2; // del1 + del2
        del("Hello World");
        MyDelegate del3 = (string msg) => Console.WriteLine("Aufgerufen Lambda-Ausdruck: ") + msg);
        del += del3; // del1 + del2 + del3
        del("Hello World");
        del = del - del2; // Entfernen del2
        del("Hello World");
        del -= del1 // Entfernen del1
        del("Hello World");
    }
}
class ClassA
{
    static void MethodA(string message)
    {
        Console.WriteLine("Aufgerufen ClassA.MethodA() mit Parameter: ") + message);
    }
}
class ClassB
{
    static void MethodB(string message)
    {
        Console.WriteLine("Aufgerufen ClassB.MethodB() mit Parameter: ") + message);
    }
}

加法和减法运算符始终作为赋值的一部分工作:del1+=del2;与del1=del1+del2完全等价;减法也是如此。

如果委托返回一个值,那么当多播委托调用时,最后分配的目标方法的值将被返回。

public delegate int MyDelegate(); //声明委托
class Program
{
    static void Main(string[] args)
    {
        MyDelegate del1 = ClassA.MethodA;
        MyDelegate del2 = ClassB.MethodB;
        MyDelegate del = del1 + del2; 
        Console.WriteLine(del());// 返回200
    }
}
class ClassA
{
    static int MethodA()
    {
        return 100;
    }
}
class ClassB
{
    static int MethodB()
    {
        return 200;
    }
}

泛型委托

可以使用与委托相同的方式定义泛型委托,但可以使用泛型type参数或返回类型。设置目标方法时,必须指定泛型类型。

例如,看以下用于int和string参数的通用委托。

public delegate T add<T>(T param1, T param2; // 泛型委托
class Program
{
    static void Main(string[] args)
    {
        add<int> sum = Sum;
        Console.WriteLine(sum(10, 20));
        add<string> con = Concat;
        Console.WriteLine(conct("Hello ", "World!!"));
    }
    public static int Sum(int val1, int val2)
    {
        return val1 + val2;
    }
    public static string Concat(string str1, string str2)
    {
        return str1 + str2;
    }
}

委托还用于声明事件和匿名方法。

 要记住的要点

  1. 委托是定义签名的引用类型数据类型。

  2. 委托类型变量可以引用具有与委托相同签名的任何方法。

  3. 语法:[访问修饰符] Delegate [返回类型] [委托名称]([参数])([access modifier] delegate [return type] [delegate name]([parameters]))

  4. Die Signatur der Zielmethode muss mit der Signatur des Delegaten übereinstimmen.

  5. Der Delegat kann wie eine gewöhnliche Funktion oder das invoke()-Verfahren aufgerufen werden.

  6. Man kann " +"oder" + Der =-Operator weist mehrere Methoden dem Delegat zu und verwendet "-"oder"-Der =-Operator löscht es. Es wird als Multicast-Delegat bezeichnet.

  7. Wenn ein Multicast-Delegat einen Wert zurückgibt, gibt er diesen von der letzten zugewiesenen Zielmethode zurück.

  8. Der Delegat wird in C# verwendet, um Ereignisse und anonyme Methoden zu deklarieren.