Earn More by Sharing What You Love
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Tim Corey
1h 9m 11s
Delegates in C# sind eine leistungsstarke Funktion, doch viele Entwickler sind mit ihrer effektiven Nutzung nicht vertraut. Das Video von Tim Corey über "Delegates in C# - Eine praktische Demonstration, einschließlich Action und Func" bietet eine gründliche Erklärung, was Delegates sind, wie man sie verwendet und warum sie nützlich sind.
In diesem Artikel erfahren Sie, was Tim über Delegates in C# weiß, und erhalten eine klare Erklärung ihrer Verwendung und praktischen Anwendungen. Sie werden lernen, wie Delegierte die Flexibilität und Effizienz Ihres Codes verbessern können, mit Beispielen wie ihrer Verwendung in einem Einkaufswagensystem.
Tim führt in das Konzept der Delegates ein und hebt deren Leistungsfähigkeit und Vielseitigkeit in C# hervor. Er versichert den Zuschauern, dass trotz einiger einschüchternder Terminologie die Grundlage der Delegierten einfach ist. Tim zielt darauf ab, Delegates zu entmystifizieren und spezielle Typen wie func und action zu behandeln.
Tim richtet eine Demo-Anwendung ein, um die Verwendung von Delegaten zu veranschaulichen. Die Lösung enthält drei Projekte: eine Konsolen-Benutzeroberfläche, eine Demo-Bibliothek und eine WinForm-Benutzeroberfläche. Der Schwerpunkt liegt zunächst auf der Console UI und der Demo Library.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleUI
{
class Program
{
static ShoppingCartModel cart = new ShoppingCartModel();
static void Main(string[] args)
{
PopulateCartWithDemoData();
Console.WriteLine($"The total for the cart is {cart.GenerateTotal():C2}");
Console.ReadLine();
}
private static void PopulateCartWithDemoData()
{
cart.Items.Add(new ProductModel { ItemName = "Cereal", Price = 3.63M });
cart.Items.Add(new ProductModel { ItemName = "Milk", Price = 2.95M });
cart.Items.Add(new ProductModel { ItemName = "Strawberries", Price = 7.51M });
cart.Items.Add(new ProductModel { ItemName = "Blueberries", Price = 6.75M });
}
}
}
public class ShoppingCartModel
{
public List<ProductModel> Items { get; set; } = new List<ProductModel>();
public decimal GenerateTotal()
{
decimal subtotal = Items.Sum(x => x.Price);
if (subtotal > 100)
{
return subtotal * 0.80M;
}
else if (subtotal > 50)
{
return subtotal * 0.85M;
}
else if (subtotal > 10)
{
return subtotal * 0.90M;
}
else
{
return subtotal;
}
}
}
public class ProductModel
{
public string ItemName { get; set; }
public decimal Price { get; set; }
}Imports System
Imports System.Collections.Generic
Imports System.Linq
Namespace ConsoleUI
Class Program
Private Shared cart As New ShoppingCartModel()
Shared Sub Main(args As String())
PopulateCartWithDemoData()
Console.WriteLine($"The total for the cart is {cart.GenerateTotal():C2}")
Console.ReadLine()
End Sub
Private Shared Sub PopulateCartWithDemoData()
cart.Items.Add(New ProductModel With {.ItemName = "Cereal", .Price = 3.63D})
cart.Items.Add(New ProductModel With {.ItemName = "Milk", .Price = 2.95D})
cart.Items.Add(New ProductModel With {.ItemName = "Strawberries", .Price = 7.51D})
cart.Items.Add(New ProductModel With {.ItemName = "Blueberries", .Price = 6.75D})
End Sub
End Class
End Namespace
Public Class ShoppingCartModel
Public Property Items As List(Of ProductModel) = New List(Of ProductModel)()
Public Function GenerateTotal() As Decimal
Dim subtotal As Decimal = Items.Sum(Function(x) x.Price)
If subtotal > 100 Then
Return subtotal * 0.80D
ElseIf subtotal > 50 Then
Return subtotal * 0.85D
ElseIf subtotal > 10 Then
Return subtotal * 0.90D
Else
Return subtotal
End If
End Function
End Class
Public Class ProductModel
Public Property ItemName As String
Public Property Price As Decimal
End ClassTim erklärt die Struktur und Funktionalität der Demo-Anwendung:
Einkaufswagen-Modell: Stellt den Einkaufswagen mit einer Liste von Artikeln (ProductModel) dar und berechnet die Gesamtkosten mit Rabatten auf Basis der Zwischensumme.
Produktmodell: Stellt einzelne Artikel mit Namen und Preiseigenschaften dar.
Konsolenanwendung: Füllt den Warenkorb mit den Demodaten, berechnet die Gesamtsumme und zeigt sie an.
Tim geht die Rabattlogik in der Methode GenerateTotal durch und erklärt, wie die Zwischensumme den angewandten Rabatt bestimmt:
Tim verwendet einen Haltepunkt, um die Berechnungs- und Rabattlogik zu veranschaulichen, um sicherzustellen, dass die Betrachter die Grundlagen verstehen, bevor sie Delegierte einführen.
In diesem Abschnitt taucht Tim Corey in das Konzept der Delegates in C# ein, erklärt, wie sie funktionieren und demonstriert ihre Verwendung anhand praktischer Codebeispiele.
Tim erklärt, dass ein Delegat im Wesentlichen eine Möglichkeit ist, Methoden als Parameter zu übergeben. Anstatt eine Variable oder eine Eigenschaft zu übergeben, übergeben Sie eine Methode, was einen flexibleren und wiederverwendbaren Code ermöglicht.
Im Folgenden erläutert Tim den Prozess der Erstellung und Verwendung eines Delegaten:
Definieren Sie den Delegaten:
public delegate void MentionDiscount(decimal subtotal);Public Delegate Sub MentionDiscount(subtotal As Decimal)Verwendung des Delegaten in einer Methode:
public decimal GenerateTotal(MentionDiscount mentionDiscount)
{
decimal subtotal = Items.Sum(x => x.Price);
// Call a method passed as a delegate
mentionDiscount(subtotal);
if (subtotal > 100)
{
return subtotal * 0.80M;
}
else if (subtotal > 50)
{
return subtotal * 0.85M;
}
else if (subtotal > 10)
{
return subtotal * 0.90M;
}
else
{
return subtotal;
}
}
Erstellen einer Methode zur Übergabe an den Delegaten:
private static void SubtotalAlert(decimal subtotal)
{
Console.WriteLine($"The subtotal is {subtotal:C2}");
}
Aufruf der Methode GenerateTotal:
class Program
{
static ShoppingCartModel cart = new ShoppingCartModel();
static void Main(string[] args)
{
PopulateCartWithDemoData();
Console.WriteLine($"The total for the cart is {cart.GenerateTotal(SubtotalAlert):C2}");
Console.ReadLine();
}
private static void PopulateCartWithDemoData()
{
cart.Items.Add(new ProductModel { ItemName = "Cereal", Price = 3.63M });
cart.Items.Add(new ProductModel { ItemName = "Milk", Price = 2.95M });
cart.Items.Add(new ProductModel { ItemName = "Strawberries", Price = 7.51M });
cart.Items.Add(new ProductModel { ItemName = "Blueberries", Price = 6.75M });
}
}
Tim führt die Anwendung aus, um zu demonstrieren, wie der Delegat funktioniert. Die Konsolenausgabe zeigt die Zwischensumme und die Gesamtsumme des Warenkorbs an, was darauf hindeutet, dass die Methode SubtotalAlert erfolgreich übergeben und über den Delegaten ausgeführt wurde.

Tim Corey erforscht dann die Verwendung von func- und action-Delegates in C#. Dies sind spezielle Arten von Delegaten, die von Microsoft bereitgestellt werden, um die Verwendung von Delegaten mit Generika zu vereinfachen.
Tim weist auf ein häufiges Problem hin: hart kodierte Rabattlogik in der Methode GenerateTotal. Dieser Ansatz ist unflexibel und erfordert Codeänderungen, Neukompilierung und erneute Bereitstellung, sobald sich die Rabattregeln ändern.
public decimal GenerateTotal()
{
decimal subtotal = Items.Sum(x => x.Price);
if (subtotal > 100)
{
return subtotal * 0.80M;
}
else if (subtotal > 50)
{
return subtotal * 0.85M;
}
else if (subtotal > 10)
{
return subtotal * 0.90M;
}
else
{
return subtotal;
}
}Public Function GenerateTotal() As Decimal
Dim subtotal As Decimal = Items.Sum(Function(x) x.Price)
If subtotal > 100 Then
Return subtotal * 0.80D
ElseIf subtotal > 50 Then
Return subtotal * 0.85D
ElseIf subtotal > 10 Then
Return subtotal * 0.90D
Else
Return subtotal
End If
End FunctionTim stellt den func-Delegaten vor, um das Problem der hart kodierten Rabatte zu lösen. Der func-Delegat ist ein generischer Delegat, der eine Methodensignatur mit einem Rückgabetyp und bis zu 16 Eingabeparametern darstellt.
Definieren des Func Delegate:
public decimal GenerateTotal(Func<List<ProductModel>, decimal, decimal> calculateDiscountedTotal)
{
decimal subtotal = Items.Sum(x => x.Price);
MentionDiscount(subtotal);
return calculateDiscountedTotal(Items, subtotal);
}
Erstellung der Rabattberechnungsmethode:
private static decimal CalculateLevelDiscount(List<ProductModel> items, decimal subtotal)
{
if (subtotal > 100)
{
return subtotal * 0.80M;
}
else if (subtotal > 50)
{
return subtotal * 0.85M;
}
else if (subtotal > 10)
{
return subtotal * 0.90M;
}
else
{
return subtotal;
}
}
Übergabe der Methode an den Func-Delegaten:
class Program
{
static ShoppingCartModel cart = new ShoppingCartModel();
static void Main(string[] args)
{
PopulateCartWithDemoData();
Console.WriteLine($"The total for the cart is {cart.GenerateTotal(CalculateLevelDiscount):C2}");
Console.ReadLine();
}
private static void PopulateCartWithDemoData()
{
cart.Items.Add(new ProductModel { ItemName = "Cereal", Price = 3.63M });
cart.Items.Add(new ProductModel { ItemName = "Milk", Price = 2.95M });
cart.Items.Add(new ProductModel { ItemName = "Strawberries", Price = 7.51M });
cart.Items.Add(new ProductModel { ItemName = "Blueberries", Price = 6.75M });
}
private static decimal CalculateLevelDiscount(List<ProductModel> items, decimal subtotal)
{
if (subtotal > 100)
{
return subtotal * 0.80M;
}
else if (subtotal > 50)
{
return subtotal * 0.85M;
}
else if (subtotal > 10)
{
return subtotal * 0.90M;
}
else
{
return subtotal;
}
}
}
Tim demonstriert die geänderte Anwendung und zeigt, dass sie korrekt funktioniert und den Rabatt auf der Grundlage der vorgegebenen Logik dynamisch berechnet.

Tim vergleicht den benutzerdefinierten Delegaten und den func-Delegaten:
Delegate: Erfordert eine explizite Definition der Signatur und eine klare Dokumentation und Struktur.
Func: Ist prägnanter, erfordert aber jedes Mal die Angabe von Eingabe- und Ausgabetypen, was weniger klar sein kann.
Beide Ansätze bieten Flexibilität, aber die Wahl hängt von dem spezifischen Anwendungsfall und der Komplexität der Anwendung ab.
Tim Corey geht auf eine häufig gestellte Frage zur Verwendung von Delegaten ein: Warum einen Delegaten haben, wenn die ganze Arbeit an anderer Stelle erledigt wird?
Tim erklärt, dass der Zweck von Delegierten darin besteht, Flexibilität und Erweiterbarkeit im Code zu ermöglichen. Die Methode GenerateTotal in der Klasse ShoppingCartModel kann mehr tun als nur Rabatte zu berechnen. Sie kann auch Aufgaben wie die Überprüfung der Lagerverfügbarkeit, die Validierung des Warenkorbinhalts oder andere Geschäftslogiken übernehmen. Mit Delegaten können Sie spezifische Methoden für spezielle Aufgaben oder benutzerdefiniertes Verhalten übergeben, ohne die Kernmethode zu ändern. Dadurch wird der Code modularer und leichter zu pflegen.
Delegierte sind besonders nützlich in Szenarien, in denen Sie:
Tim stellt den Action-Delegaten vor, einen weiteren speziellen Typ von Delegaten in C#. Der Action-Delegat ist ähnlich wie Func, gibt aber keinen Wert zurück (d. h., er liefert void).
Erstellen des Action Delegate:
public decimal GenerateTotal(Func<List<ProductModel>, decimal, decimal> calculateDiscountedTotal, Action<string> tellUserWeAreDiscounting)
{
decimal subtotal = Items.Sum(x => x.Price);
MentionSubtotal(subtotal);
tellUserWeAreDiscounting("We are applying your discount.");
return calculateDiscountedTotal(Items, subtotal);
}
Erstellung der Alert-Methode:
private static void AlertUser(string message)
{
Console.WriteLine(message);
}
Übergabe der Methode an den Aktionsdelegaten:
class Program
{
static ShoppingCartModel cart = new ShoppingCartModel();
static void Main(string[] args)
{
PopulateCartWithDemoData();
Console.WriteLine($"The total for the cart is {cart.GenerateTotal(CalculateLevelDiscount, AlertUser):C2}");
Console.ReadLine();
}
private static void PopulateCartWithDemoData()
{
cart.Items.Add(new ProductModel { ItemName = "Cereal", Price = 3.63M });
cart.Items.Add(new ProductModel { ItemName = "Milk", Price = 2.95M });
cart.Items.Add(new ProductModel { ItemName = "Strawberries", Price = 7.51M });
cart.Items.Add(new ProductModel { ItemName = "Blueberries", Price = 6.75M });
}
private static decimal CalculateLevelDiscount(List<ProductModel> items, decimal subtotal)
{
if (subtotal > 100)
{
return subtotal * 0.80M;
}
else if (subtotal > 50)
{
return subtotal * 0.85M;
}
else if (subtotal > 10)
{
return subtotal * 0.90M;
}
else
{
return subtotal;
}
}
private static void AlertUser(string message)
{
Console.WriteLine(message);
}
}
Tim zeigt, wie man anonyme Methoden verwendet, die es ermöglichen, Methoden spontan zu definieren, ohne sie zu benennen.
Definieren anonymer Methoden:
class Program
{
static ShoppingCartModel cart = new ShoppingCartModel();
static void Main(string[] args)
{
PopulateCartWithDemoData();
Console.WriteLine($"The total for the cart is {cart.GenerateTotal((items, subtotal) =>
{
if (subtotal > 100) return subtotal * 0.80M;
else if (subtotal > 50) return subtotal * 0.85M;
else if (subtotal > 10) return subtotal * 0.90M;
else return subtotal;
},
(message) => Console.WriteLine(message)):C2}");
Console.ReadLine();
}
private static void PopulateCartWithDemoData()
{
cart.Items.Add(new ProductModel { ItemName = "Cereal", Price = 3.63M });
cart.Items.Add(new ProductModel { ItemName = "Milk", Price = 2.95M });
cart.Items.Add(new ProductModel { ItemName = "Strawberries", Price = 7.51M });
cart.Items.Add(new ProductModel { ItemName = "Blueberries", Price = 6.75M });
}
}
Verständnis der Syntax:
=>-Operator (Lambda-Ausdruck), um den Methodenrumpf direkt inline zu definieren.Durch die Verwendung von Delegaten, einschließlich Func-, Action- und anonymen Methoden, können Entwickler dynamischeren und modularen Code erstellen, der flexible und wiederverwendbare Komponenten ermöglicht.
In diesem Segment demonstriert Tim Corey die Leistungsfähigkeit von Delegaten, indem er ihre Verwendung auf eine WinForms-Anwendung ausweitet. Dabei wird hervorgehoben, wie Delegierte unterschiedliche Verhaltensweisen in verschiedenen Kontexten der Benutzeroberfläche (UI) erleichtern können.
WinForms-Benutzeroberfläche mit zwei Schaltflächen :
Das Formular hat zwei Schaltflächen: eine zur Demonstration von Nachrichtenfeldern und eine zur Demonstration von Textfeldern.
Das ShoppingCartModel und eine Methode, es mit Demodaten zu füllen, sind ebenfalls enthalten.
public partial class Dashboard : Form
{
ShoppingCartModel cart = new ShoppingCartModel();
public Dashboard()
{
InitializeComponent();
PopulateCartWithDemoData();
}
private void PopulateCartWithDemoData()
{
cart.Items.Add(new ProductModel { ItemName = "Cereal", Price = 3.63M });
cart.Items.Add(new ProductModel { ItemName = "Milk", Price = 2.95M });
cart.Items.Add(new ProductModel { ItemName = "Strawberries", Price = 7.51M });
cart.Items.Add(new ProductModel { ItemName = "Blueberries", Price = 6.75M });
}
private void messageBoxDemoButton_Click(object sender, EventArgs e)
{
decimal total = cart.GenerateTotal(SubtotalAlert, CalculateLevelDiscount, PrintOutDiscountAlert);
MessageBox.Show($"The total is {total:C2}");
}
private void textBoxDemoButton_Click(object sender, EventArgs e)
{
// Code for TextBox demo will go here
}
}Public Partial Class Dashboard
Inherits Form
Private cart As New ShoppingCartModel()
Public Sub New()
InitializeComponent()
PopulateCartWithDemoData()
End Sub
Private Sub PopulateCartWithDemoData()
cart.Items.Add(New ProductModel With {.ItemName = "Cereal", .Price = 3.63D})
cart.Items.Add(New ProductModel With {.ItemName = "Milk", .Price = 2.95D})
cart.Items.Add(New ProductModel With {.ItemName = "Strawberries", .Price = 7.51D})
cart.Items.Add(New ProductModel With {.ItemName = "Blueberries", .Price = 6.75D})
End Sub
Private Sub messageBoxDemoButton_Click(sender As Object, e As EventArgs) Handles messageBoxDemoButton.Click
Dim total As Decimal = cart.GenerateTotal(AddressOf SubtotalAlert, AddressOf CalculateLevelDiscount, AddressOf PrintOutDiscountAlert)
MessageBox.Show($"The total is {total:C2}")
End Sub
Private Sub textBoxDemoButton_Click(sender As Object, e As EventArgs) Handles textBoxDemoButton.Click
' Code for TextBox demo will go here
End Sub
End ClassPrintOutDiscountAlert :
private void PrintOutDiscountAlert(string message)
{
MessageBox.Show(message);
}
Zwischensummenalarm :
private void SubtotalAlert(decimal subtotal)
{
MessageBox.Show($"The subtotal is {subtotal:C2}");
}
Berechne den Stufenrabatt :
private decimal CalculateLevelDiscount(List<ProductModel> items, decimal subtotal)
{
if (items.Count > 3)
{
return subtotal - 3M;
}
return subtotal - items.Count;
}
Verwendung von Delegaten im Button Click Event:
messageBoxDemoButton_Click-Methode demonstriert, wie die Delegaten an die GenerateTotal-Methode übergeben und die Ergebnisse mit Nachrichtenfeldern gehandhabt werden.private void messageBoxDemoButton_Click(object sender, EventArgs e)
{
decimal total = cart.GenerateTotal(SubtotalAlert, CalculateLevelDiscount, PrintOutDiscountAlert);
MessageBox.Show($"The total is {total:C2}");
}
Ausführen der Anwendung:

Tim Corey erklärt Delegates in C# anschaulich und geht dabei auf die Grundlagen, die fortgeschrittene Verwendung und praktische Beispiele wie die Verwendung von Delegates in einem Einkaufswagen ein. Er zeigt, wie Delegates flexiblen und wiederverwendbaren Code ermöglichen, einschließlich Func, Action und anonyme Methoden. Sehen Sie sich das vollständige Video an und erfahren Sie, wie Sie Delegierte in Ihren Projekten effektiv einsetzen können!
Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!
Join our newsletter, you’ll get exclusive access on article updates. We value your privacy