C# von den Grundlagen bis zum Profi — Folge 5
Weitergabe von Aktionen über Delegierte, Ereignisse und Lambdas
Die in diesem Blog verfassten Artikel wurden mit dem Ziel erstellt, zu unterrichten. Außerdem können die Informationen im Artikel falsch sein, also seien Sie bitte vorsichtig.
Methoden können direkt aufgerufen werden, es kann aber auch die später auszuführende Aktion selbst als Wert übergeben werden. Delegaten, Ereignisse und Lambdas in C# drücken diesen Ablauf aus.
delegieren
int Double(int value) => value * 2;
Func<int, int> operation = Double;
int result = operation(10);
Action<string> logger = message => Console.WriteLine(message);
logger("Battle started");
Func<int, int> ist eine Aktion, die einen int empfängt und einen int zurückgibt, und Action ist eine Aktion, die keinen Rückgabewert hat. Der aufrufende Code muss nicht wissen, welche Methode tatsächlich ausgeführt wird.
Ereignis
public sealed class Player
{
public event Action<int>? HealthChanged;
public int Health { get; private set; } = 100;
public void TakeDamage(int amount)
{
Health = Math.Max(0, Health - amount);
HealthChanged?.Invoke(Health);
}
}
player.HealthChanged += health => healthBar.SetValue(health);
Ereignisse benachrichtigen zustandsbehaftete Objekte über Änderungen und bewirken, dass andere Objekte, z. B. Benutzeroberflächen oder Sounds, reagieren. Von außen können Sie sich nur an- und abmelden, Veranstaltungen können nicht nach Belieben aufgerufen werden.
Abonnement-Lebensdauerverwaltung
void OnEnable()
{
player.HealthChanged += UpdateHealth;
}
void OnDisable()
{
player.HealthChanged -= UpdateHealth;
}
Wenn ein kurzlebiges Objekt weiterhin Ereignisse eines langlebigen Objekts abonniert, bleiben möglicherweise Speicher und Aufrufe erhalten. Der registrierte Standort und der entsprechende Freigabeort müssen gemeinsam ermittelt werden.
Lambda-Erfassung
int bonus = 5;
Func<int, int> addBonus = damage => damage + bonus;
Wenn ein Lambda eine externe lokale Variable verwendet, kann ein Objekt zum Speichern des Werts erstellt werden. Wenn Sie weiterhin Capture-Lambdas in Code erstellen, der sich in jedem Frame wiederholt, kann dies zu unnötigen Zuweisungen führen.
Delegierte sind Arten von Aktionen, und Ereignisse schaffen Grenzen für Änderungsbenachrichtigungen. Das Ersetzen aller Aufrufe durch Ereignisse aus Gründen der Bequemlichkeit macht es schwierig, die Ausführungsreihenfolge zu verfolgen. Daher sollte es dort verwendet werden, wo eine lose Kopplung erforderlich ist.