C# Delegat
In C# ist ein Delegat ein typsicherer Funktionszeiger, der es ermöglicht, Methoden als Parameter an andere Methoden zu übergeben.
Delegaten in C# sind Funktionszeigern in C oder C++ ähnlich.DelegatIst eine Referenztypvariable, die einen Verweis auf eine Methode enthält; der Verweis kann zur Laufzeit geändert werden.
Delegaten sind in C# sehr verbreitet und werden für Ereignisbehandlung, Rückruffunktionen, LINQ und andere Vorgänge verwendet.
Alle Delegaten leiten von derSystem.Delegate-Klasse ab.
Deklaration eines Delegaten
Ein Delegat ist ein Referenztyp, der eine Methodensignatur definiert und verwendet werden kann, um eine zu dieser Signatur passende Methode zu speichern. Über ein Delegat können Sie Methoden in anderen Klassen aufrufen.
Die Delegatdeklaration bestimmt, auf welche Methoden das Delegat verweisen kann. Ein Delegat kann auf eine Methode mit derselben Signatur verweisen.
Die Syntax zum Deklarieren eines Delegaten lautet wie folgt:
public delegate <return type> <delegate-name> <parameter list>
Chinesische Formatbeschreibung:
public delegate 返回类型 委托名(参数类型 参数名, ...);
Zum Beispiel definiert der folgende Code einen Delegaten, der zwei ganze Zahlen entgegennimmt und eine ganze Zahl zurückgibt:
public delegate int MathOperation(int x, int y);
Der Delegat im folgenden Beispiel kann verwendet werden, um auf jede Methode zu verweisen, die einen einzelnenstring-Parameter besitzt und eineint-Typvariable zurückgibt.
public delegate int MyDelegate (string s);
Delegat instanziieren (Delegate)
Sobald ein Delegattyp deklariert ist, muss ein Delegatobjekt mit demnew-Schlüsselwort erstellt werden, und es wird einer bestimmten Methode zugeordnet. Beim Erstellen eines Delegaten wird das Argument, das an dienew-Anweisung übergeben wird, wie ein Methodenaufruf geschrieben, jedoch ohne die Parameter. Zum Beispiel:
...
printString ps1 = new printString(WriteToScreen);
printString ps2 = new printString(WriteToFile);
Das folgende Beispiel veranschaulicht die Deklaration, Instanziierung und Verwendung eines Delegaten, der verwendet werden kann, um auf eine Methode zu verweisen, die einen ganzzahligen Parameter entgegennimmt und einen ganzzahligen Wert zurückgibt.
Beispiel
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)
{
// Eine Delegateninstanz erstellen
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
// Delegatobjekt verwenden, um Methode aufzurufen
nc1(25);
Console.WriteLine("Wert von Num: {0}", getNum());
nc2(5);
Console.WriteLine("Wert von Num: {0}", getNum());
Console.ReadKey();
}
}
}
Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er das folgende Ergebnis:
Value of Num: 35 Value of Num: 175
Multicasting eines Delegaten
Delegatobjekte können verwendet werden;+sie werden mit dem Operator kombiniert.
Ein kombinierter Delegat ruft die beiden Delegaten auf, die er kombiniert; nur Delegaten desselben Typs können kombiniert werden.
-Der Operator kann verwendet werden, um einen Komponenten-Delegaten aus einem kombinierten Delegaten zu entfernen.
Mithilfe dieses nützlichen Features von Delegaten können Sie eine Aufrufliste von Methoden erstellen, die aufgerufen werden, wenn der Delegat aufgerufen wird. Dies wird alsMulticast (Multicasting)eines Delegaten bezeichnet, auch Multicast genannt.
Das folgende Programm demonstriert das Multicasting von Delegaten:
Beispiel
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)
{
// Eine Delegateninstanz erstellen
NumberChanger nc;
NumberChanger nc1 = new NumberChanger(AddNum);
NumberChanger nc2 = new NumberChanger(MultNum);
nc = nc1;
nc += nc2;
// Multicast aufrufen
nc(5);
Console.WriteLine("Wert von Num: {0}", getNum());
Console.ReadKey();
}
}
}
Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er das folgende Ergebnis:
Value of Num: 75
Der Zweck von Delegaten
Das folgende Beispiel veranschaulicht die Verwendung von Delegaten. Der DelegatprintStringkann verwendet werden, um auf eine Methode zu verweisen, die eine Zeichenfolge als Eingabe akzeptiert und nichts zurückgibt.
Wir verwenden diesen Delegaten, um zwei Methoden aufzurufen: Die erste gibt die Zeichenfolge auf der Konsole aus, und die zweite schreibt die Zeichenfolge in eine Datei:
Beispiel
using System.IO;
namespace DelegateAppl
{
class PrintString
{
static FileStream fs;
static StreamWriter sw;
// Delegatdeklaration
public delegate void printString(string s);
// Diese Methode gibt auf der Konsole aus
public static void WriteToScreen(string str)
{
Console.WriteLine("Der String ist: {0}", str);
}
// Diese Methode schreibt in eine Datei
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();
}
// Diese Methode nimmt einen Delegaten als Parameter entgegen und verwendet ihn, um eine Methode aufzurufen
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();
}
}
}
Wenn der obige Code kompiliert und ausgeführt wird, erzeugt er das folgende Ergebnis:
The String is: Hello World
Delegat entfernen
Wenn Sie eine Methode nicht mehr benötigen, können Sie den-=Operator verwenden, um die Methode aus der Delegatenkette zu entfernen.
Beispiel
{
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;
// Die Methode PrintLowerCase entfernen
print -= PrintLowerCase;
// Aufruf des Delegaten (ruft nur PrintUpperCase auf)
print("Hello, C#"); // Ausgabe: HELLO, C#
}
}
Delegaten und Ereignisse
Delegaten werden oft zusammen mit Ereignissen verwendet. Ein Ereignis ist ein spezieller Delegattyp, der für den Publish/Subscribe-Mechanismus verwendet wird.
In C# ist ein Ereignis im Wesentlichen ein Typ, der einen Delegaten kapselt, und es wird verwendet, um auf bestimmte Operationen im Programm zu reagieren.
Beispiel
{
// Ein Ereignis definieren
public event EventHandler Click;
// Methode zum Auslösen eines Ereignisses
public void OnClick()
{
if (Click != null)
{
Click(this, EventArgs.Empty); // Ereignis auslösen
}
}
}
public class Program
{
public static void Main()
{
Button button = new Button();
// Ereignis abonnieren
button.Click += Button_Click;
// Ereignis auslösen
button.OnClick(); // Ausgabe "Button geklickt!"
}
private static void Button_Click(object sender, EventArgs e)
{
Console.WriteLine("Button geklickt!");
}
}
Delegattypen
C# bietet mehrere gängige Delegattypen:
1. Action
Action: Stellt eine Methode dar, die keinen Wert zurückgibt. Sie kann bis zu 16 Parameter akzeptieren.
Action<string> printMessage = Console.WriteLine;
printMessage("Hello");
2. Func
Func: Stellt eine Methode dar, die einen Rückgabewert hat. Sie akzeptiert bis zu 16 Parameter; der erste Parameter ist der Eingabeparameter, und der letzte Parameter ist der Rückgabetyp.
Func<int, int, int> add = (x, y) => x + y; Console.WriteLine(add(3, 4)); // 输出 7
3. Predicate
Predicate: Stellt eine Methode dar, die einen bool-Wert zurückgibt und üblicherweise für bedingte Prüfungen verwendet wird.
Predicate<int> isEven = x => x % 2 == 0; Console.WriteLine(isEven(4)); // 输出 True
Hinweise zu Delegaten
Typsicherheit:Delegaten sind typsicher, was bedeutet, dass nur Methoden mit übereinstimmenden Signaturen einem Delegaten zugewiesen werden können.
Anonyme Methoden und Lambda-Ausdrücke: Sie können anonyme Methoden oder Lambda-Ausdrücke verwenden, um Delegateninstanzen zu erstellen, was den Code vereinfacht.
Func<int, int, int> add = (x, y) => x + y; Console.WriteLine(add(5, 3)); // 输出 8
Asynchroner Aufruf: Sie können Delegaten zusammen mit den Methoden BeginInvoke und EndInvoke verwenden, um asynchrone Aufrufe durchzuführen.
Delegaten sind ein sehr leistungsfähiges und flexibles Feature in C#, das helfen kann, ereignisgesteuerte Programmierung, Callback-Mechanismen und funktionale Programmierstile zu implementieren. Sie bieten nicht nur die Möglichkeit, Code wiederzuverwenden, sondern verbessern auch die Modularität von Programmen. Das Verständnis und die Beherrschung der Verwendung von Delegaten sind sehr wichtig für die C#-Programmierung.
Weitere Erweiterungen