Un delegado es un placeholder para un método. Permite pasar una función como parámetro a un método.
Hay varios tipos de delegado:
Action<T>
consume una clase, devuelvevoid
EjemploConsole.WriteLine();
Predicate<T>
consume una clase, devuelvebool
Por ejemplo para abstraer condicionesFunc<T, K>
consume una clase y devuelve otra. Por ejemplo para abstraer mappings
Usaremos el struct Book
para todos los ejemplos
public struct Book
{
public string Title; // Title of the book.
public string Author; // Author of the book.
public decimal Price; // Price of the book.
public bool Paperback; // Is it paperback?
public Book(string title, string author, decimal price, bool paperBack)
{
Title = title;
Author = author;
Price = price;
Paperback = paperBack;
}
}
Action (Consumer)
Tenemos el ejemplo BookDBActionService
public class BookDBActionService
{
// List of all books in the database
List<Book> list = new List<Book>();
// initialize test data on constructor
public BookDBActionService()
{
list.Add(new Book("title1", "author1", 10, true));
list.Add(new Book("title2", "author2", 20, false));
}
// Aqui tenemos el Action<Book> donde delegamos como se procesa cada libro
public void ProcessPaperbackBooks(Action<Book> processBook)
{
foreach (Book b in list)
{
if (b.Paperback)
{
// delegate call
processBook(b);
}
}
}
}
Llamada donde ejecutamos el código y llamamos al Action<Book>
public static void Main(string[] args)
{
var bookDBAction = new BookDBActionService();
bookDBAction.ProcessPaperbackBooks(book => Console.WriteLine(book.Title));
}
Predicate (Condition)
public class BookDBPredicateService
{
// List of all books in the database
List<Book> list = new List<Book>();
// initialize test data on constructor
public BookDBPredicateService()
{
list.Add(new Book("title1", "author1", 10, true));
list.Add(new Book("title2", "author2", 20, false));
}
// Aqui tenemos el Predicate<Book> con el condicional de cada libro
public void ProcessPaperbackBooks(Predicate<Book> processBook)
{
foreach (Book book in list)
{
// delegate call
if (processBook.Invoke(book))
{
Console.WriteLine($" book title {book.Title}");
}
}
}
}
Llamada donde ejecutamos el código y llamamos al Predicate<Book>
public static void Main(string[] args)
{
var bookDBPredicate = new BookDBPredicateService();
bookDBPredicate.ProcessPaperbackBooks(book => !book.Paperback);
}
Func
public class BookDBFuncService
{
// List of all books in the database
List<Book> list = new List<Book>();
// initialize test data on constructor
public BookDBFuncService()
{
list.Add(new Book("title1", "author1", 10, true));
list.Add(new Book("title2", "author2", 20, false));
}
// Aqui tenemos el Func<Book, string> donde mapeamos cada libro
public List<string> ProcessPaperbackBooks(Func<Book, string> processBook)
{
var fields = new List<string>();
foreach (Book b in list)
{
if (b.Paperback)
{
// delegate call
fields.Add(processBook(b));
}
}
return fields;
}
}
Llamada donde ejecutamos el código y llamamos al Func<Book, string>
public static void Main(string[] args)
{
var bookDBFunc = new BookDBFuncService();
var extractedFields = bookDBFunc.ProcessPaperbackBooks(book => book.Title);
}