Unterricht + Übung Tag 4

This commit is contained in:
Max
2026-08-14 08:03:46 +02:00
parent ade7a28e1d
commit 10334c1bc7
22 changed files with 633 additions and 17 deletions
+96
View File
@@ -0,0 +1,96 @@
using System;
namespace _15_Delegates;
// C# hat für Lambda-Ausdrücke und Methodenreferenzen ein eigenes Konzept: Die Delegates.
// Das Prinzip dahinter ist ähnlich den "functional Interfaces".
public delegate int Vergleich(int a, int b); // Hier erstellen wir einen neuen Datentypen 'Vergleich', welcher nun int-Methoden mit zwei int-Parametern annehmen kann. Einer Variable dieses Datentyps können wir alle Methoden zuweisen, deren Methodensignatur zum Delegaten passt. Für die Signatur ist wichtig: Rückgabetyp und Parametertypen und -anzahl.
internal class Delegates
{
public static void Main(string[] args)
{
// Mit dem Delegate-Datentypen erzeugen wir eine Variable, der wir einen Lambda-Ausdruck zuweisen.
// Der Lambda-Ausdruck ist hier eine anonyme Methode, die festlegt, wie die Sortierreihenfolge eines Sortieralgorithmus sein soll.
// Siehe: CompareTo()-Methode
Vergleich v = (x, y) =>
{
if (x > y)
return 1;
else if (y > x)
return -1;
else
return 0;
};
int[] array = { 9, 1, 8, 2, 7, 3, 6, 4, 5 };
BubbleSort(array, v);
Console.WriteLine(String.Join(", ", array));
// Vordefinierte Delegates in C# sind unter anderem:
Action<int> action; // Void-Methode mit bis zu 16 Parametern. (Vergleich zum Consumer in Java)
Func<int, double> func; // Methode mit beliebigem Return-Typ und bis zu 16 Parametern. (Vergleich zum Function-Interface in Java)
Predicate<int> predicate; // Boolean-Methode mit einem Parameter. (Wie Predicate in Java)
Comparison<string> comparison; // Integer-Methode mit zwei Parametern vom selben Typ. (Wie Comparator in Java)
EventHandler eventHandler; // Wird für Events verwendet (Observer Pattern).
// Beispiel für Events:
Button b = new Button();
b.Text = "Ich bin ein Button";
b.OnClick += ButtonClicked; // Das Event wird durch += abonniert. Hier wird dem Delegaten die Referenz auf die ButtonClicked()-Methode zugewiesen.
b.OnClick += ButtonClicked;
b.OnClick -= ButtonClicked; // Mit -= können Events wieder de-abonniert werden.
b.OnClick += (s, e) => Console.WriteLine("Über Lambda-Ausdruck");
b.Click(); // Auf den Button klicken...
// Multicast:
Action<string> a;
a = Console.WriteLine;
a += (s) => Console.WriteLine(s.ToUpper());
a += (s) => Console.WriteLine(s.Substring(0, s.Length / 2));
a.Invoke("Hallo, Welt!"); // Alle zugewiesenen Methoden werden nacheinander aufgerufen.
Delegate[] invocationList = a.GetInvocationList();
invocationList[1].DynamicInvoke("Dynamisch aufgerufen");
}
//Ein Sortieralgorithmus, bei dem durch Übergabe des Delegates bestimmt wird, wie sortiert werden soll (Aufsteigend oder Absteigend)
public static void BubbleSort(int[] array, Vergleich vergleich)
{
if (vergleich == null) // Wir prüfen zuerst, ob überhaupt eine Methode übergeben wurde...
return;
for (int i = 0; i < array.Length; i++)
{
for (int j = 0; j < array.Length - 1 - i; j++)
{
if (vergleich(array[j], array[j + 1]) == 1) // Aufruf der Methode im Delegate. Dazu können wir den Delegate wie eine Methode verwenden.
{
// Zwei Elemente tauschen:
/*int temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;*/
// Der Tausch von zwei Variablen in einem Schritt über Tupel:
(array[j], array[j + 1]) = (array[j + 1], array[j]);
}
}
}
}
// EventHandler-Methode: Diese muss zur Signatur des EventHandler-Delegaten passen.
public static void ButtonClicked(object? sender, EventArgs e)
{
Console.WriteLine((sender as Button)?.Text);
Console.WriteLine("Der Klick wurde verarbeitet...");
}
}