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
Les délégués dans C# sont une fonctionnalité puissante, pourtant de nombreux développeurs ne sont pas familiers avec leur utilisation efficace. La vidéo de Tim Corey intitulée "Delegates in C# - A practical demonstration, including Action and Func" explique en détail ce que sont les délégués, comment les utiliser et pourquoi ils sont utiles.
Cet article vous apportera les conseils d'expert de Tim sur les délégués en C#, en offrant une explication claire de leur utilisation et de leurs applications pratiques. Vous apprendrez comment les délégués peuvent améliorer la flexibilité et l'efficacité de votre code, avec des exemples comme leur utilisation dans un système de panier d'achat.
Tim présente le concept des délégués, en soulignant leur puissance et leur polyvalence en C#. Il assure les téléspectateurs qu'en dépit d'une terminologie intimidante, la base des délégués est simple. Tim vise à démystifier les délégués et à couvrir les types spéciaux tels que func et action.
Tim met en place une application de démonstration pour illustrer l'utilisation des délégués. La solution contient trois projets : une interface console, une bibliothèque de démonstration et une interface WinForm. Dans un premier temps, l'accent est mis sur l'interface utilisateur de la console et la bibliothèque de démonstration.
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 explique la structure et les fonctionnalités de l'application de démonstration :
Modèle de panier : Représente le panier d'achat avec une liste d'articles (ProductModel) et calcule le coût total avec des remises basées sur le sous-total.
Modèle de produit : Représente les articles individuels avec des propriétés de nom et de prix.
Application console : Remplit le panier avec les données de démonstration, calcule le total et l'affiche.
Tim présente la logique de remise dans la méthode GenerateTotal, en expliquant comment le sous-total détermine la remise appliquée :
Tim utilise un point d'arrêt pour démontrer la logique de calcul et de remise, afin de s'assurer que les spectateurs comprennent les fondements avant d'introduire les délégués.
Dans cette section, Tim Corey plonge dans le concept des délégués en C#, en expliquant leur fonctionnement et en démontrant leur utilisation à l'aide d'exemples de code pratiques.
Tim explique qu'un délégué est essentiellement un moyen de passer des méthodes en tant que paramètres. Au lieu de passer une variable ou une propriété, vous passez une méthode, ce qui permet un code plus flexible et réutilisable.
Voici comment Tim décompose le processus de création et d'utilisation d'un délégué :
Définir le délégué :
public delegate void MentionDiscount(decimal subtotal);Public Delegate Sub MentionDiscount(subtotal As Decimal)Utilisation du délégué dans une méthode :
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;
}
}
Création d'une méthode à passer au délégué :
private static void SubtotalAlert(decimal subtotal)
{
Console.WriteLine($"The subtotal is {subtotal:C2}");
}
Appel de la méthode 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 exécute l'application pour démontrer le fonctionnement du délégué. La console affiche le sous-total et le total du panier, ce qui indique que la méthode SubtotalAlert a été transmise et exécutée avec succès par l'intermédiaire du délégué.

Tim Corey explore ensuite l'utilisation des délégués func et action en C#. Il s'agit de types spéciaux de délégués fournis par Microsoft pour simplifier l'utilisation des délégués avec les génériques.
Tim met en évidence un problème courant : la logique de remise codée en dur dans la méthode GenerateTotal. Cette approche n'est pas flexible et nécessite des modifications du code, une recompilation et un redéploiement chaque fois que les règles d'actualisation changent.
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 introduit le délégué func pour résoudre le problème des remises codées en dur. Le délégué func est un délégué générique qui représente une signature de méthode avec un type de retour et jusqu'à 16 paramètres d'entrée.
Définition du délégué Func :
public decimal GenerateTotal(Func<List<ProductModel>, decimal, decimal> calculateDiscountedTotal)
{
decimal subtotal = Items.Sum(x => x.Price);
MentionDiscount(subtotal);
return calculateDiscountedTotal(Items, subtotal);
}
Création de la méthode de calcul des remises :
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;
}
}
Passer la méthode au délégué Func :
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 fait une démonstration de l'application modifiée, montrant qu'elle fonctionne correctement et qu'elle calcule dynamiquement la remise en fonction de la logique fournie.

Tim compare le délégué personnalisé et le délégué func :
Délégué : Nécessite une définition explicite de la signature, en fournissant une documentation et une structure claires.
Func : Plus concis, mais nécessite de spécifier les types d'entrée et de sortie à chaque fois, ce qui peut être moins clair.
Les deux approches sont flexibles, mais le choix dépend du cas d'utilisation spécifique et de la complexité de l'application.
Tim Corey répond à une question fréquente sur l'utilisation des délégués : Pourquoi avoir un délégué si tout le travail semble être fait ailleurs ?
Tim explique que l'objectif des délégués est d'assurer la flexibilité et l'extensibilité du code. La méthode GenerateTotal de la classe ShoppingCartModel peut faire plus que calculer des remises. Elle peut également prendre en charge des tâches telles que la vérification de la disponibilité des stocks, la validation du contenu du panier ou d'autres logiques commerciales. Les délégués vous permettent de passer des méthodes spécifiques pour des tâches uniques ou un comportement personnalisé sans modifier la méthode principale. Cela rend le code plus modulaire et plus facile à maintenir.
Les délégués sont particulièrement utiles dans les scénarios où vous souhaitez.. :
Tim présente le délégué Action, un autre type spécial de délégué en C#. Le délégué Action est similaire à Func, mais il ne renvoie pas de valeur (c'est-à-dire qu'il renvoie void).
Création du délégué d'action :
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);
}
Création de la méthode d'alerte :
private static void AlertUser(string message)
{
Console.WriteLine(message);
}
Passer la méthode au délégué d'action :
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 montre comment utiliser les méthodes anonymes, qui permettent de définir des méthodes à la volée sans les nommer.
Définition des méthodes anonymes :
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 });
}
}
Comprendre la syntaxe :
=> (expression lambda) pour définir le corps de la méthode directement en ligne.En utilisant les délégués, y compris les méthodes Func, Action et anonymes, les développeurs peuvent créer un code plus dynamique et plus modulaire, ce qui permet d'obtenir des composants flexibles et réutilisables.
Dans ce segment, Tim Corey démontre la puissance des délégués en étendant leur utilisation à une application WinForms. Elle met en évidence la manière dont les délégués peuvent faciliter différents comportements dans divers contextes d'interface utilisateur (UI).
WinForm UI avec deux boutons :
Le formulaire comporte deux boutons : l'un pour la démonstration des boîtes de message et l'autre pour la démonstration des boîtes de texte.
Le modèle ShoppingCartModel et une méthode pour le remplir avec des données de démonstration sont également inclus.
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);
}
SubtotalAlert :
private void SubtotalAlert(decimal subtotal)
{
MessageBox.Show($"The subtotal is {subtotal:C2}");
}
CalculerLevelDiscount :
private decimal CalculateLevelDiscount(List<ProductModel> items, decimal subtotal)
{
if (items.Count > 3)
{
return subtotal - 3M;
}
return subtotal - items.Count;
}
Utilisation de délégués dans l'événement de clic de bouton :
messageBoxDemoButton_Click démontre comment passer les délégués à la méthode GenerateTotal et gérer les résultats à l'aide de boîtes de message.private void messageBoxDemoButton_Click(object sender, EventArgs e)
{
decimal total = cart.GenerateTotal(SubtotalAlert, CalculateLevelDiscount, PrintOutDiscountAlert);
MessageBox.Show($"The total is {total:C2}");
}
Exécuter l'application :

Tim Corey explique clairement les délégués en C#, en couvrant leurs bases, leur utilisation avancée et des exemples pratiques comme l'utilisation des délégués dans un panier d'achat. Il montre comment les délégués permettent un code flexible et réutilisable, y compris les méthodes Func, Action et anonymes. Regardez la vidéo complète vidéo pour apprendre à utiliser efficacement les délégués dans vos projets !
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