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
Os delegates em C# são um recurso poderoso, mas muitos desenvolvedores não estão familiarizados com seu uso eficaz. O vídeo de Tim Corey sobre " Delegates em C# - Uma demonstração prática, incluindo Action e Func " oferece uma explicação completa do que são delegates, como usá-los e por que são úteis.
Este artigo fornecerá a você as informações especializadas de Tim sobre delegates em C#, oferecendo uma explicação clara de seu uso e aplicações práticas. Você aprenderá como os delegates podem aumentar a flexibilidade e a eficiência do seu código, com exemplos como seu uso em um sistema de carrinho de compras.
Tim apresenta o conceito de delegates, destacando seu poder e versatilidade em C#. Ele garante aos espectadores que, apesar de alguma terminologia intimidante, a base dos delegados é simples. Tim pretende desmistificar os delegados e abordar tipos especiais como func e action.
Tim configura um aplicativo de demonstração para ilustrar o uso de delegados. A solução contém três projetos: uma interface de usuário de console, uma biblioteca de demonstração e uma interface de usuário WinForm. Inicialmente, o foco será na interface do usuário do console e na biblioteca de demonstrações.
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 explica a estrutura e a funcionalidade do aplicativo de demonstração:
Modelo de Carrinho de Compras : Representa o carrinho de compras com uma lista de itens (ProductModel) e calcula o custo total com descontos com base no subtotal.
Modelo de produto : Representa itens individuais com propriedades de nome e preço.
Aplicativo de console : Preenche o carrinho com dados de demonstração, calcula o total e o exibe.
Tim explica a lógica de desconto no método GenerateTotal, detalhando como o subtotal determina o desconto aplicado:
Tim utiliza um ponto de interrupção para demonstrar a lógica de cálculo e desconto, garantindo que os espectadores compreendam os fundamentos antes de apresentá-los aos participantes.
Nesta seção, Tim Corey explora o conceito de delegates em C#, explicando como funcionam e demonstrando seu uso com exemplos práticos de código.
Tim explica que um delegate é essencialmente uma forma de passar métodos como parâmetros. Em vez de passar uma variável ou uma propriedade, você passa um método, o que permite um código mais flexível e reutilizável.
Eis como Tim explica o processo de criação e utilização de um delegado:
Defina o Delegado :
public delegate void MentionDiscount(decimal subtotal);Public Delegate Sub MentionDiscount(subtotal As Decimal)Utilizando o Delegado em um Método :
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;
}
}
Criando um método para passar para o delegado :
private static void SubtotalAlert(decimal subtotal)
{
Console.WriteLine($"The subtotal is {subtotal:C2}");
}
Chamando o método 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 executa o aplicativo para demonstrar como o delegado funciona. A saída do console mostra o subtotal e o total do carrinho, indicando que o método SubtotalAlert foi passado e executado com sucesso por meio do delegado.

Tim Corey então explora o uso de funções e delegados de ação em C#. Esses são tipos especiais de delegados fornecidos pela Microsoft para simplificar o uso de delegados com genéricos.
Tim destaca um problema comum: a lógica de desconto codificada diretamente no método GenerateTotal. Essa abordagem é inflexível e exige alterações de código, recompilação e reimplementação sempre que as regras de desconto mudam.
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 apresenta o delegado func para resolver o problema do desconto fixo no código. O delegado func é um delegado genérico que representa a assinatura de um método com um tipo de retorno e até 16 parâmetros de entrada.
Definindo o Delegado Func :
public decimal GenerateTotal(Func<List<ProductModel>, decimal, decimal> calculateDiscountedTotal)
{
decimal subtotal = Items.Sum(x => x.Price);
MentionDiscount(subtotal);
return calculateDiscountedTotal(Items, subtotal);
}
Criação do método de cálculo de desconto :
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;
}
}
Passando o método para o delegado da função :
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 demonstra a aplicação modificada, mostrando que ela funciona corretamente e calcula dinamicamente o desconto com base na lógica fornecida.

Tim compara o delegado personalizado e o delegado funcional:
Delegado : Requer definição explícita da assinatura, fornecendo documentação e estrutura claras.
Func : Mais conciso, mas exige a especificação dos tipos de entrada e saída a cada vez, o que pode ser menos claro.
Ambas as abordagens oferecem flexibilidade, mas a escolha depende do caso de uso específico e da complexidade da aplicação.
Tim Corey aborda uma pergunta comum sobre o uso de delegados: Por que ter um delegado se todo o trabalho parece ser feito em outro lugar?
Tim explica que o objetivo dos delegates é proporcionar flexibilidade e extensibilidade ao código. O método GenerateTotal na classe ShoppingCartModel pode fazer mais do que apenas calcular descontos. Também pode lidar com tarefas como verificar a disponibilidade de estoque, validar o conteúdo do carrinho ou outras lógicas de negócios. Os delegates permitem que você passe métodos específicos para tarefas únicas ou comportamentos personalizados sem alterar o método principal. Isso torna o código mais modular e mais fácil de manter.
Os delegados são especialmente úteis em cenários onde você deseja:
Tim apresenta o delegado Action, outro tipo especial de delegado em C#. O delegado Action é semelhante ao Func, mas não retorna um valor (ou seja, retorna void).
Criando o Delegado de Ação :
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);
}
Criando o método de alerta :
private static void AlertUser(string message)
{
Console.WriteLine(message);
}
Passando o método para o delegado de ação :
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 mostra como usar métodos anônimos, permitindo que você defina métodos dinamicamente sem precisar nomeá-los.
Definindo Métodos Anônimos :
Em vez de criar métodos nomeados, você pode definir os métodos diretamente onde eles são necessários.
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 });
}
}
Compreendendo a sintaxe :
=> (expressão lambda) para definir o corpo do método diretamente no lugar.Ao utilizar delegates, incluindo Func, Action e métodos anônimos, os desenvolvedores podem criar um código mais dinâmico e modular, permitindo componentes flexíveis e reutilizáveis.
Neste segmento, Tim Corey demonstra o poder dos delegates, estendendo seu uso a um aplicativo WinForms. Isso destaca como os delegados podem facilitar diferentes comportamentos em vários contextos de interface do usuário (IU).
Interface de usuário WinForm com dois botões :
O formulário possui dois botões: um para exibir caixas de mensagem e outro para exibir caixas de texto.
O modelo ShoppingCartModel e um método para preenchê-lo com dados de demonstração também estão incluídos.
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}");
}
CalcularDescontoPorNível :
private decimal CalculateLevelDiscount(List<ProductModel> items, decimal subtotal)
{
if (items.Count > 3)
{
return subtotal - 3M;
}
return subtotal - items.Count;
}
Utilizando Delegados no Evento de Clique de Botão :
messageBoxDemoButton_Click demonstra como passar os delegados para o método GenerateTotal e manipular os resultados usando caixas de mensagem.private void messageBoxDemoButton_Click(object sender, EventArgs e)
{
decimal total = cart.GenerateTotal(SubtotalAlert, CalculateLevelDiscount, PrintOutDiscountAlert);
MessageBox.Show($"The total is {total:C2}");
}
Executando o aplicativo :

Tim Corey explica os delegates em C# de forma clara, abordando os conceitos básicos, o uso avançado e exemplos práticos, como a utilização de delegates em um carrinho de compras. Ele demonstra como os delegates permitem um código flexível e reutilizável, incluindo Func, Action e métodos anônimos. Assista ao vídeo completo para aprender como aplicar delegados de forma eficaz em seus projetos!
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