Jak: deklarovat, konkretizovat a použití delegáta (Příručka programování C#)
C# 1.0 a novější jak je znázorněno v následujícím příkladu lze deklarovat delegátů.
// Declare a delegate.
delegate void Del(string str);
// Declare a method with the same signature as the delegate.
static void Notify(string name)
{
Console.WriteLine("Notification received for: {0}", name);
}
// Create an instance of the delegate.
Del del1 = new Del(Notify);
C# 2.0 umožňuje jednodušší zápis předchozí prohlášení, jak ukazuje následující příklad.
// C# 2.0 provides a simpler way to declare an instance of Del.
Del del2 = Notify;
C# 2.0 a novější, je také možné použít anonymní metody deklarovat a inicializace delegáta, jak ukazuje následující příklad.
// Instantiate Del by using an anonymous method.
Del del3 = delegate(string name)
{ Console.WriteLine("Notification received for: {0}", name); };
C# 3.0 a novější Delegáti také být deklarován a vytvoření instance pomocí lambda výraz, jak ukazuje následující příklad.
// Instantiate Del by using a lambda expression.
Del del4 = name => { Console.WriteLine("Notification received for: {0}", name); };
Další informace naleznete v tématu Lambda výrazy (Příručka programování C#).
Následující příklad ukazuje deklaraci, konkretizaci a používání delegát.BookDB Třídy zapouzdří bookstore databáze, která udržuje databázi knih.Poskytuje metody, ProcessPaperbackBooks, která nalezne všechny paperback knihy v databázi a volá delegát pro každou z nich.delegate s názvem typ, který je použit ProcessBookDelegate.Test Třída používá k tisku, nadpisy a průměrná cena formátu brožované knihy této třídy.
Použití Delegáti propaguje dobré oddělení funkcí mezi databází knihkupectvích a kód klienta.Kód klienta nemá žádný ukládání knih nebo jak kód bookstore najde formátu brožované knihy.Kód bookstore nemá žádný jaké zpracování se provádí na formátu brožované knihy po nalezne.
Příklad
// A set of classes for handling a bookstore:
namespace Bookstore
{
using System.Collections;
// Describes a book in the book list:
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;
}
}
// Declare a delegate type for processing a book:
public delegate void ProcessBookDelegate(Book book);
// Maintains a book database.
public class BookDB
{
// List of all books in the database:
ArrayList list = new ArrayList();
// Add a book to the database:
public void AddBook(string title, string author, decimal price, bool paperBack)
{
list.Add(new Book(title, author, price, paperBack));
}
// Call a passed-in delegate on each paperback book to process it:
public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
{
foreach (Book b in list)
{
if (b.Paperback)
// Calling the delegate:
processBook(b);
}
}
}
}
// Using the Bookstore classes:
namespace BookTestClient
{
using Bookstore;
// Class to total and average prices of books:
class PriceTotaller
{
int countBooks = 0;
decimal priceBooks = 0.0m;
internal void AddBookToTotal(Book book)
{
countBooks += 1;
priceBooks += book.Price;
}
internal decimal AveragePrice()
{
return priceBooks / countBooks;
}
}
// Class to test the book database:
class TestBookDB
{
// Print the title of the book.
static void PrintTitle(Book b)
{
System.Console.WriteLine(" {0}", b.Title);
}
// Execution starts here.
static void Main()
{
BookDB bookDB = new BookDB();
// Initialize the database with some books:
AddBooks(bookDB);
// Print all the titles of paperbacks:
System.Console.WriteLine("Paperback Book Titles:");
// Create a new delegate object associated with the static
// method Test.PrintTitle:
bookDB.ProcessPaperbackBooks(PrintTitle);
// Get the average price of a paperback by using
// a PriceTotaller object:
PriceTotaller totaller = new PriceTotaller();
// Create a new delegate object associated with the nonstatic
// method AddBookToTotal on the object totaller:
bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
System.Console.WriteLine("Average Paperback Book Price: ${0:#.##}",
totaller.AveragePrice());
}
// Initialize the book database with some test books:
static void AddBooks(BookDB bookDB)
{
bookDB.AddBook("The C Programming Language", "Brian W. Kernighan and Dennis M. Ritchie", 19.95m, true);
bookDB.AddBook("The Unicode Standard 2.0", "The Unicode Consortium", 39.95m, true);
bookDB.AddBook("The MS-DOS Encyclopedia", "Ray Duncan", 129.95m, false);
bookDB.AddBook("Dogbert's Clues for the Clueless", "Scott Adams", 12.00m, true);
}
}
}
/* Output:
Paperback Book Titles:
The C Programming Language
The Unicode Standard 2.0
Dogbert's Clues for the Clueless
Average Paperback Book Price: $23.97
*/
Robustní programování
Deklaraci delegáta.
Následující příkaz prohlašuje nový typ delegáta.
public delegate void ProcessBookDelegate(Book book);
Každý typ delegáta popisuje počet a typy argumentů a typ vrácené hodnoty metody, které můžete zapouzdřit.Vždy, když je potřeba nová sada typ argumentu nebo vrácené hodnoty typu, musí být deklarován nový typ delegáta.
Konkretizace delegáta.
Po prohlásil typ delegáta delegát objektu musí být vytvořen a spojené s určitou metodu.V předchozím příkladu provedete předáním PrintTitle metodu ProcessPaperbackBooks metodu jako v následujícím příkladu:
bookDB.ProcessPaperbackBooks(PrintTitle);
Vytvoří nový objekt delegát spojené s statické metody Test.PrintTitle.Podobně nejsou statické metody AddBookToTotal na objektu totaller je předán jako v následujícím příkladu:
bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
V obou případech je předán nový objekt delegovat ProcessPaperbackBooks metoda.
Po vytvoření delegát metoda je spojen s nikdy změny; Delegát objekty jsou neměnné.
Volání delegáta.
Po vytvoření objektu delegát delegát objektu je obvykle předáno jiný kód, který bude volat delegáta.Delegát objektu se nazývá pomocí názvu objektu delegáta, následovaná v závorkách argumenty předávané delegáta.Následuje příklad volání delegáta:
processBook(b);
Delegát může být buď volána synchronně, jako v následujícím příkladu nebo asynchronně pomocí BeginInvoke a EndInvoke metod.
Viz také
Referenční dokumentace
Události (Příručka programování C#)
Delegáti (Příručka programování C#)