«delegierter» methoden schablone funktionszeigeramrhein/skripten/info2/02.delegates.pdf · ein c#...

37
Delegates und Ereignisse «Delegierter» Methoden Schablone Funktionszeiger Dr. Beatrice Amrhein

Upload: phungquynh

Post on 06-Feb-2018

221 views

Category:

Documents


1 download

TRANSCRIPT

Delegates und Ereignisse

«Delegierter»

� Methoden Schablone

� Funktionszeiger

Dr. Beatrice Amrhein

Ü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

3

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

12Nach dem Handbuch der .NET 4.0-Programmierung, Rolf Wenger, 2012

Zweites Beispiel

Rechner

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

EreignisseEreignisse

20Nach 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 einfaches Beispiel

25

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

Beispiel

Timer

29Nach 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

Beispiel

� Überwachte Eigenschaft

� Ereignis-Argumente

33

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