Jak deklarovat, vytvořit instanci a použít delegáta (Průvodce programováním v C#)

Delegáty můžete deklarovat pomocí některé z následujících metod:

  • Deklarujte typ delegáta a deklarujte metodu s odpovídajícím podpisem:
// 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: {name}");
}
// Create an instance of the delegate.
Del del1 = new Del(Notify);
  • Přiřazení skupiny metod k typu delegáta:
// C# 2.0 provides a simpler way to declare an instance of Del.
Del del2 = Notify;
  • Deklarujte anonymní metodu:
// Instantiate Del by using an anonymous method.
Del del3 = delegate(string name)
    { Console.WriteLine($"Notification received for: {name}"); };
  • Použijte výraz lambda:
// Instantiate Del by using a lambda expression.
Del del4 = name =>  { Console.WriteLine($"Notification received for: {name}"); };

Další informace najdete v tématu Výrazy lambda.

Následující příklad znázorňuje deklarování, vytváření instancí a použití delegáta. Třída BookDB zapouzdřuje databázi bookstore, která udržuje databázi knih. Zveřejňuje metodu, ProcessPaperbackBookskterá najde všechny knihy zpětného papíru v databázi a zavolá delegáta pro každou z nich. Použitý delegate typ má název ProcessBookCallback. Třída Test používá tuto třídu k tisku názvů a průměrné ceny papírových knih.

Použití delegátů podporuje dobré oddělení funkčnosti mezi databází knihkupectví a klientským kódem. Klientský kód nemá žádné znalosti o tom, jak jsou knihy uloženy nebo jak kód knihkupectví najde papírové knihy. Kód knihkupectví nemá žádné znalosti o tom, jaké zpracování se provádí na papírových knihách poté, co je najde.

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 ProcessBookCallback(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(ProcessBookCallback 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 Test
    {
        // Print the title of the book.
        static void PrintTitle(Book b)
        {
            Console.WriteLine($"   {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:
            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);

            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í

  • Deklarování delegáta.

    Následující příkaz deklaruje nový typ delegáta.

    public delegate void ProcessBookCallback(Book book);
    

    Každý typ delegáta popisuje počet a typy argumentů a typ návratové hodnoty metod, které může zapouzdřovat. Pokaždé, když je potřeba nová sada typů argumentů nebo návratový typ hodnoty, musí být deklarován nový typ delegáta.

  • Vytvoření instance delegáta

    Po deklaraci typu delegáta musí být objekt delegáta vytvořen a přidružen k určité metodě. V předchozím příkladu to uděláte předáním PrintTitle metody metodě ProcessPaperbackBooks jako v následujícím příkladu:

    bookDB.ProcessPaperbackBooks(PrintTitle);
    

    Tím se vytvoří nový delegovat objekt přidružený ke statické metodě Test.PrintTitle. Podobně se ne statická metoda AddBookToTotal objektu předává jako v následujícím příkladu totaller :

    bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
    

    V obou případech se do metody předá nový objekt delegáta ProcessPaperbackBooks .

    Po vytvoření delegáta je metoda přidružená k nikdy změnám; delegování objektů je neměnné.

  • Volání delegáta

    Po vytvoření objektu delegáta se objekt delegáta obvykle předá jinému kódu, který delegáta zavolá. Objekt delegáta se volá pomocí názvu objektu delegáta, následovaného závorky argumenty, které mají být předány delegátu. Následuje příklad volání delegáta:

    processBook(b);
    

    Delegát se může volat synchronně, například v tomto příkladu, nebo asynchronně pomocí BeginInvoke a EndInvoke metod.

Viz také