Post on 06-Feb-2018
Überblick
� Definition eines Delegat
� Einfache Delegate
� Beispiele von Delegat-Anwendungen
� Definition eines Ereignisses� Definition eines Ereignisses
� Einfache Ereignisse
� Beispiele von Ereignissen
2Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Definition
� Ein Delegat ist ein Typ, der eine Referenz (Zeiger) auf eine Methode beschreibt.
� Delegate entsprechen den Funktionszeigern in C++, sie sind jedoch typsicher und geschützt.
� Delegate ermöglichen es, Methoden als Parameter zu übergeben.übergeben.
� Delegate können miteinander verkettet werden (nacheinander ausgeführt).
4Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Hinweis
� Delegate bilden die Grundlage für Ereignisse (wie z.B. für Benutzer-Eingaben).
� Durch das Verketten von Delegaten können mehrere Methoden an ein Ereignis angebunden werden.
� Alle miteinander verketteten Delegate werden gemeinsam (nacheinander) aufgerufen.(nacheinander) aufgerufen.
5Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Deklaration
� Die Deklaration von einem Delegat sieht ähnlich aus wie eine Methodensignatur.
� Sie benötigt das Schlüsselwort delegate
� Sie hat einen Rückgabewert und eine beliebige Anzahl Parameter:
<sichtbarkeit> delegate <Resultat-Typ> <Delegat-Name> (<Parameter-Liste>)
Zwei Beispiele:
public delegate void meinDelegat1(int n, string message);
public delegate int meinDelegat2(object m, double d);
6Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Benutzen von Delegates
Der Einsatz von Delegates erfolgt in drei Schritten.
1. Deklaration des Delegate
public delegate int meinDelegate( string s, int i )
2. Definieren des Delegate-Objekt mit der entsprechenden Methode
meinDelegate delegateName = methode;meinDelegate delegateName = methode;
3. Aufruf des Delegate-Objekts und dadurch indirekter Aufruf der Methode
int resultat = delegateName("Eingabe", 17);
7Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
8Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Erstes einfaches Beispiel: Verschiedene Ausgabe-Funktionen
Ein C# Beispiel: Die Klasse Ausgabe
Die Klasse Ausgabe hat zwei verschiedene Methoden zum Schreiben (auf die Konsole und in eine Datei) mit gleicher Signatur.
using System;
using System.IO;
class Ausgabe
{
// Schreiben auf die Konsole
public static void WriteToScreen(string str)public static void WriteToScreen(string str)
{ Console.WriteLine("Ausgabe: {0}", str); }
//Schreiben in die Datei Test.txt
const string fileName = "C:\\tmp\\Test.txt";
public static void WriteToFile(string s)
{ File.AppendAllText(fileName, s); }
9Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Die Klasse Ausgabe
// Deklaration des Delegaten mit gleicher Signatur
// wie die beiden Methoden WriteToScreen und WriteToFile)
public delegate void SchreibeDelegate(string s);
10Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Das Hauptprogramm
//Benutze die Delegates
static void Main(string[] args)
{
SchreibeDelegate psDelegate;
string text = "Hier ist mein Text für dieses Beispiel";
//Zuweisen und ausführen der Methode «Schreibe auf den Schirm» //Zuweisen und ausführen der Methode «Schreibe auf den Schirm»
psDelegate = WriteToScreen;
psDelegate(text);
// Zuweisen und ausführen der Methode «Schreibe ins File»
psDelegate = WriteToFile;
psDelegate(text);
}
11Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Die Klasse Rechner
Die Klasse Rechner hat vier verschiedene Rechnungs-Methoden mit gleicher Signatur.
class Rechner
{
public static double Addition(double x, double y)
{ return x + y; }
public static double Subtraktion(double x, double y)
{ return x - y; }{ return x - y; }
public static double Multiplikation(double x, double y)
{ return x * y; }
public static double Division(double x, double y)
{ return x / y; }
}
13Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Das Hauptprogramm
// Deklaration des Delegate � gleiche Signatur wie die Methoden von Rechner
public delegate double RechnungsOperation(double d1, double d2);
class Program
{
static void Main(string[] args)
{
// Initialisierung des Delegats// Initialisierung des Delegats
RechnungsEinheit berechne = Rechner.Addition;
do
{
// Einlesen der Operation
Console.Write("Operation: +, -, * oder / ");
char wahl = Console.ReadLine()[0];
14Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Das Hauptprogramm
// Zuweisen der ausgewählten Operation � der richtigen Methode
switch (wahl)
{
case '+':
berechne = Rechner.Addition; break;
case '-':
berechne = Rechner.Subtraktion; break;
case '*':
berechne = Rechner.Multiplikation; break;berechne = Rechner.Multiplikation; break;
case '/':
berechne = Rechner.Division; break;
}
15Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Das Hauptprogramm
// Aufruf der Operation '+', '-', '*' oder '/' über das Delegat
double resultat = berechne(input1, input2);
// Ausgabe des Resultats
Rechner.Ausgabe(wahl, x, y, resultat);
Console.WriteLine("Beenden mit q, weiter mit w: ");
} while (Console.ReadLine() != "q");
}
}
16Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Verwenden von Delegaten als Parameter
17Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Die Methode Ausgabe
Wir wählen nochmals das ursprüngliche Delegat RechnungsOperation:
public delegate double RechnungsOperation(double d1, double d2);
Die Methode Ausgabe hat als vierten Parameter eine Rechnungs-Operation (also ein Delegat)
public static void Ausgabe(double d1, double d2, char c,
RechnungsOperation berechne)
{ . . . }
18Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Die Methode Ausgabe
Die so übergebene Funktion kann dann innerhalb der Methode verwendet werden:
public static void Ausgabe(double d1, double d2, char c,
RechnungsOperation berechne)
{
Console.WriteLine("{0} {1} {2} = {3}\n",
d1, c, d2, berechne(d1, d2));d1, c, d2, berechne(d1, d2));
}
19Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Definition
� Events oder Ereignisse dienen dazu, Informationen über eingetretene Benutzer-Eingaben oder Daten-Änderungen an andere Klassen oder Objekte zu übermitteln.
� Die Klasse, die das Ereignis sendet (oder auslöst), wird als Herausgeber (Publisher) bezeichnet
� Die Klassen, welche das Ereignis empfangen (oder behandeln), � Die Klassen, welche das Ereignis empfangen (oder behandeln), werden als Abonnenten (Subscriber) bezeichnet.
21Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Definition
� Das abstrakte Modell
22Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Eigenschaften
� Der Herausgeber bestimmt, wann ein Ereignis ausgelöst wird.
� Die Abonnenten bestimmen (durch ihre Event-Methoden), wie auf ein Ereignis reagiert werden soll.
� Ein Ereignis kann mehrere Abonnenten haben. Die Anmeldung geschieht über +=
� Ein Abonnent kann sich wieder abmelden durch -=� Ein Abonnent kann sich wieder abmelden durch -=
� Ein Abonnent kann mehrere Ereignisse von verschiedenen Herausgebern behandeln.
� Ereignisse, die keine Abonnenten haben, werden unterdrückt (nicht ausgelöst).
23Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Eigenschaften
� Ereignisse dienen normalerweise zur Signalisierung von Benutzeraktionen wie das Klicken auf Schaltflächen oder Auswählen von Menüs in der grafischen Benutzeroberfläche.
� Wenn ein Ereignis mehrere Abonnenten hat, werden die Ereignis-Methoden aller Abonnenten (nacheinander) aufgerufen.
� Ereignisse basieren auf Delegaten
� Sie benutzen die C#-Klasse EventArgs (Ereignis-Argumente) zum Übergeben von Informationen.
24Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Die Klasse Herausgeber
public class Herausgeber
{// Definiere ein Delegat und eine EreignisBehandler Liste
public delegate void EreignisDelegat(EreignisArgument s);
public event EreignisDelegat ereignisBehandler;
// Anmelden einer Ereignis-Methode
public void Registriere(EreignisDelegat s)
{
ereignisBehandler += s;ereignisBehandler += s;
}
// Publiziere ein Ereignis.
public void publiziere(String m)
{
EreignisArgument ea = new EreignisArgument(m);
ereignisBehandler(ea);
}
}
26Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Die Klasse Abonnent
Die Klasse Abonnent habe zwei Methoden, welche die Methoden-Schablone (Delegat) erfüllen.
public class Abonnent
{
public void EventMethode1(EreignisArgument s)
{ Console.WriteLine(s.meldung + " ist angekommen"); }
public void EventMethode2(EreignisArgument s)
{ Console.WriteLine(s.meldung + " wird behandelt"); }{ Console.WriteLine(s.meldung + " wird behandelt"); }
}
public class EreignisArgument : EventArgs
{
public string meldung;
public EreignisArgument(String s)
{ this.meldung = s; }
}
27Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Das Hauptprogramm
Dies Event Methoden der Klasse Abonnent können als Ereignis-Behandlungs-Methode angemeldet werden.
class Program
{
static void Main()
{
Herausgeber herausgeber = new Herausgeber();
Abonnent abo = new Abonnent();
//Registriere Abonnent-Methoden als Ereignis-Behandler
herausgeber.Registriere(abo.EventMethode1);
herausgeber.Registriere(abo.EventMethode2);
//Der Herausgeber erzeugt ein Ereignis
herausgeber.publiziere("Ereignis 17");
Console.ReadLine();
}
}
28Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Die Klasse Zeitgeber � Der Herausgeber
public class Zeitgeber
{
public delegate void EreignisDelegat(TickArgument e);
private event EreignisDelegat ereignisBehandler;
// Uhr starten
public void Start()
{
while (true)
{
TickArgument te = new TickArgument(DateTime.Now);TickArgument te = new TickArgument(DateTime.Now);
ereignisBehandler(te);
System.Threading.Thread.Sleep(1000); // eine Sekunde warten
}
}
public void Registriere(ZeitEmpfaenger m)
{ ereignisBehandler += m.Ausgabe; }
}
30Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Die Klasse ZeitEmpfaenger � Der Abonnent
// Der Abonnent
public class ZeitEmpfaenger
{
public void Ausgabe(TickArgument e)
{
System.Console.Clear();
System.Console.WriteLine("\n {0:G}", e.Time);
}
}
//Die Ereignis Argumente
public class TickArgument : EventArgs
{
public DateTime Time;
public TickArgument(DateTime t)
{ this.Time = t; }
}
31Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Ein C# Beispiel: Das Hauptprogramm
Das Hauptprogramm erzeugt den Herausgeber (Zeitgeber) und den Abonnenten (ZeitEmpfaenger), dann registriert sich der Zeitgeber beimZeitEmpfaenger, zuletzt wird der Zeitgeber (die Uhr) gestartet.
class Program
{
static void Main()static void Main()
{
Zeitgeber m = new Zeitgeber();
ZeitEmpfaenger l = new ZeitEmpfaenger();
m.Registriere(l);
m.Start();
}
}
32Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Die Klasse Informationstraeger � Der Herausgeber
Die Klasse Informationstraeger verbreitet an alle (angemeldeten) Abonnenten ihre Information(en), sobald diese sich ändern.
public class Informationstraeger
{
public delegate void EreignisDelegat(EreignisArgumente e);
private event EreignisDelegat ereignisBehandler;
private string information; // überwachte Information
public void Registrierung(Abonnent abo)
{{
ereignisBehandler += abo.InfoEmpfang;
}
public void setInformation(string n)
{
this.information = n;
EreignisArgumente ea = new EreignisArgumente(information);
ereignisBehandler(ea);
}
}
34Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Die setInformation Methode dient zum Ändern der Information und benachrichtigt über die Änderung
Die Klasse MeinAbonnent � Informations-Empfänger
Die Methode InfoEmpfang der Klasse MeinAbonnent wird jedes Mal aufgerufen, sobald sich die Information beim Informationsträger ändert.
public class Abonnent
{
public void InfoEmpfang(EreignisArgumente e)
{
Console.WriteLine("\nNeue Info: {0}", e.meldung);
}
}}
35Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Die Klasse MeinAbonnent � Informations-Empfänger
Die Klasse EreignisArgumente dient zum Übertragen der neuen Informationen (Meldungen) an die angemeldeten Abonnenten.
public class EreignisArgumente : EventArgs
{
public string meldung;
public EreignisArgumente(String s)
{ this.meldung = s; }
}
36Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012
Das Hauptprogramm
Die Main Methode erzeugt zuerst den Informationsträger und dann einen Abonnenten. Der Abonnent wird dann beim Informationsträger registriert. Die Methode setInfo ändert die Information beim Informationsträger, was die Benachrichtigung des Abonnenten auslöst.
class Program
{
static void Main(string[] args)
{{
Informationstraeger infoTraeger = new Informationstraeger();
Abonnent abonnent = new Abonnent();
infoTraeger.Registrierung(abonnent);
infoTraeger.setInformation("Spielstand 2:0");
infoTraeger.setInformation("Spielstand 3:1");
infoTraeger.setInformation("Spielstand 4:2");
Console.ReadLine();
}
}
37Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012