Skip to content

Commit 09df0d2

Browse files
committed
Revise L21
1 parent 471ced0 commit 09df0d2

1 file changed

Lines changed: 129 additions & 8 deletions

File tree

21_Delegaten.md

Lines changed: 129 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
33
author: Sebastian Zug, Galina Rudolf & André Dietrich
44
email: sebastian.zug@informatik.tu-freiberg.de
5-
version: 1.0.7
5+
version: 1.0.8
66
language: de
77
narrator: Deutsch Female
88
comment: Grundidee, Multicast Delegaten, Anonyme/Lambda Funktionen, generische Delegaten, Action und Func
@@ -37,6 +37,8 @@ import: https://raw.githubusercontent.com/TUBAF-IfI-LiaScript/VL_Softwareentwick
3737

3838
[Projektaufgaben](https://github.com/ComputerScienceLecturesTUBAF/SoftwareentwicklungSoSe2023_Projektaufgaben)
3939

40+
> Bitte teilen Sie Ihr Repo mit uns! Schreiben Sie dazu eine Einladungsemail an Frau Dr. Rudolf.
41+
4042
## Motivation und Konzept der Delegaten
4143

4244
Ihre Aufgabe besteht darin folgendes Code-Fragment so umzuarbeiten, so dass
@@ -138,6 +140,24 @@ int main()
138140
```
139141
@LIA.evalWithDebug(`["main.c"]`, `gcc -Wall main.c -o a.out`, `./a.out`)
140142
143+
Und auch noch ein Python Beispiel, um die Anwendung in einer nicht typisierte Sprache zu zeigen:
144+
145+
```python
146+
def quadriere(x):
147+
return x * x
148+
149+
def wende_an(funktion, wert):
150+
print("Wende Funktion an:", funktion.__name__)
151+
result = funktion(wert)
152+
print("Ergebnis:", result)
153+
return result
154+
155+
ergebnis = wende_an(quadriere, 5)
156+
print(ergebnis) # Ausgabe: 25
157+
```
158+
@LIA.eval(`["main.py"]`, `none`, `python3 main.py`, `*`)
159+
160+
141161
### Grundidee
142162

143163
> Merke: Ein Delegat ist ein Methodentyp und dient zur Deklaration von Variablen,
@@ -150,7 +170,7 @@ Für die Anwendung sind drei Vorgänge nötig:
150170
3. Aufruf der Instanz
151171

152172
```csharp Concept.cs
153-
// Schritt 1
173+
// Schritt 1 - Spezifikation
154174
//[Zugriffsattribut] delegate Rückgabewert DelegatenName(Parameterliste);
155175
public delegate int Rechenoperation(int x, int y);
156176

@@ -282,8 +302,6 @@ Sollten wir uns mit dem Aufruf einer Methode zufrieden geben?
282302
```csharp MultiCast
283303
using System;
284304
using System.Reflection;
285-
using System.Collections.Generic;
286-
287305

288306
public class Program
289307
{
@@ -324,6 +342,37 @@ public class Program
324342
@LIA.eval(`["main.cs"]`, `mcs main.cs`, `mono main.exe`)
325343

326344
> **Merke:** Es werden alle referenzierten Methoden ausgeführt - der Rückgabewert des Aufrufes entspricht dem der letzten Methode.
345+
> Wir haben es nicht mit einer Verkettung von Methoden zu tuen, sondern mit einer Liste separater Aufrufe!
346+
347+
```csharp ChainedMultiCast
348+
using System;
349+
using System.Reflection;
350+
351+
public class Program
352+
{
353+
public delegate int Transformierer(int eingabe);
354+
355+
static int Verdoppeln(int x) => x * 2;
356+
static int PlusEins(int x) => x + 1;
357+
static int Quadrieren(int x) => x * x;
358+
359+
static Transformierer Verkette(Transformierer a, Transformierer b)
360+
{
361+
return x => b(a(x)); // Ergebnis von a wird an b weitergereicht
362+
}
363+
364+
public static void Main(string[] args){
365+
Transformierer pipeline = Verkette(Verdoppeln, PlusEins);
366+
pipeline = Verkette(pipeline, Quadrieren);
367+
368+
int ergebnis = pipeline(3); // ((3 * 2) + 1)^2 = 49
369+
Console.WriteLine(ergebnis); // Ausgabe: 49
370+
}
371+
}
372+
```
373+
@LIA.eval(`["main.cs"]`, `mcs main.cs`, `mono main.exe`)
374+
375+
327376

328377

329378
### Schnittstellen vs. Delegaten
@@ -361,8 +410,7 @@ Methode zur Methodensignatur des Delegaten passt.
361410
| ---------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------ |
362411
| repräsentiert eine Methodensignatur | wenn eine Klasse eine Schnittstelle implementiert, dann implementiert sie deren gesamte Methoden |
363412
| lässt sich nur auf Methoden anwenden | deckt sowohl Methoden als auch Eigenschaften ab |
364-
| verwendbar, wenn ein Delegat im Scope verfügbar ist | kann nur verwendet werden, wenn die Klasse diese Schnittstelle implementiert |
365-
| wird für die Behandlung von Ereignissen verwendet | findet keine Anwendung bei der Behandlung von Ereignissen. |
413+
| wird für die Behandlung von Ereignissen verwendet | |
366414
| kann auf anonyme Methoden zugreifen | kann nicht auf anonyme Methoden zugreifen. |
367415
| beim Zugriff auf eine Methode über Delegaten ist kein Zugriff auf das Objekt der Klasse erforderlich | beim Methodenzugriff benötigen Sie das Objekt der Klasse, die eine Schnittstelle implementiert |
368416
| unterstützt keine Vererbung | unterstützt Vererbung |
@@ -505,7 +553,7 @@ Das Erstellen anonymer Methoden verkürzt den Code, da nunmehr ein Codeblock als
505553

506554
```csharp
507555
// Declare a delegate pointing at an anonymous function.
508-
Del d = delegate(int k) { /* ... */ };
556+
DelgatenType d = delegate(int k) { /* ... */ };
509557

510558
```
511559
Das folgende Codebeispiel illustriert die Verwendung. Dabei wird auch deutlich, wie
@@ -574,7 +622,7 @@ public class Program
574622
```
575623
@LIA.eval(`["main.cs"]`, `mcs main.cs`, `mono main.exe`)
576624

577-
Jeder Lambdaausdruck kann in einen Delegat-Typ konvertiert werden. Der Delegattyp, in den ein Lambdaausdruck konvertiert werden kann, wird durch die Typen seiner Parameter und Rückgabewerte definiert.
625+
Jeder Lambdaausdruck kann in einen Delegat-Typ konvertiert werden. Der Delegat-Typ, in den ein Lambdaausdruck konvertiert werden kann, wird durch die Typen seiner Parameter und Rückgabewerte definiert.
578626

579627
```csharp LambdaDelegate
580628
using System;
@@ -728,6 +776,79 @@ Console.WriteLine(MyLambdaAction("Tests"));
728776

729777
Warum würde die Verwendung von Action an dieser Stelle einen Fehler generieren?
730778

779+
## Abgrenzung zu c++
780+
781+
> Gibt es in C++ Delegaten?
782+
783+
In C++ gibt es kein direktes Äquivalent zu C#-Delegaten. Stattdessen werden in C++ Funktionszeiger oder Funktionsobjekte (auch bekannt als Funktoren) verwendet, um ähnliche Funktionalitäten zu erreichen.
784+
785+
```c++ CppDelegates.cpp
786+
#include <iostream>
787+
#include <functional> // std::function, std::bind
788+
using namespace std;
789+
790+
// Normale Funktion
791+
void PrintHello(string text)
792+
{
793+
cout << text << endl;
794+
}
795+
796+
// Normale Funktion
797+
void Square(int x)
798+
{
799+
cout << "This is method Square(int x)" << endl;
800+
cout << x * x << endl;
801+
}
802+
803+
// Funktion mit Rückgabewert
804+
int SquareReturn(int x)
805+
{
806+
return x * x;
807+
}
808+
809+
int main()
810+
{
811+
// --- Funktionszeiger ---
812+
void (*myOutput)(string) = PrintHello;
813+
myOutput("Das ist eine Textausgabe");
814+
815+
// --- Funktionsobjekt (Lambda) ---
816+
auto myLambdaAction = [](string text) {
817+
cout << text << " modifiziert durch Lambda" << endl;
818+
};
819+
myLambdaAction("Tests");
820+
821+
// --- Funktionsobjekt (Lambda mit Rückgabewert) ---
822+
auto myFuncOutput = [](int x) {
823+
return x * x;
824+
};
825+
cout << myFuncOutput(5) << endl;
826+
827+
// --- std::function mit freier Funktion ---
828+
std::function<void(string)> f1 = PrintHello;
829+
f1("Ausgabe über std::function mit freier Funktion");
830+
831+
// --- std::function mit Lambda ---
832+
std::function<void(string)> f2 = [](string t) {
833+
cout << "Lambda via std::function: " << t << endl;
834+
};
835+
f2("Test");
836+
837+
// --- std::function mit std::bind (z. B. um Argumente zu binden) ---
838+
std::function<void()> f3 = std::bind(Square, 7);
839+
f3(); // Gibt 49 aus
840+
841+
// --- std::function mit Rückgabewert ---
842+
std::function<int(int)> f4 = SquareReturn;
843+
cout << "Quadrat über std::function<int(int)>: " << f4(6) << endl;
844+
845+
return 0;
846+
}
847+
```
848+
@LIA.eval(`["main.cpp"]`, `g++ -Wall main.cpp -o main`, `./main`)
849+
850+
851+
731852
## Aufgaben der Woche
732853
733854
- [ ] Vertiefen Sie das Erlernte anhand von zusätzichen Materialien

0 commit comments

Comments
 (0)