Share via


Een gemachtigde declareren, instantiëren en een gemachtigde gebruiken (C#-programmeerhandleiding)

U kunt gemachtigden declareren met een van de volgende methoden:

  • Declareer een gemachtigdentype en declareer een methode met een overeenkomende handtekening:
// Declare a delegate.
delegate void NotifyCallback(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.
NotifyCallback del1 = new NotifyCallback(Notify);
  • Wijs een methodegroep toe aan een gemachtigd type:
// C# 2.0 provides a simpler way to declare an instance of NotifyCallback.
NotifyCallback del2 = Notify;
  • Een anonieme methode declareren:
// Instantiate NotifyCallback by using an anonymous method.
NotifyCallback del3 = delegate(string name)
    { Console.WriteLine($"Notification received for: {name}"); };
  • Een lambda-expressie gebruiken:
// Instantiate NotifyCallback by using a lambda expression.
NotifyCallback del4 = name =>  { Console.WriteLine($"Notification received for: {name}"); };

Zie Lambda-expressies voor meer informatie.

Het volgende voorbeeld illustreert het declareren, instantiëren en gebruiken van een gemachtigde. De BookDB klasse bevat een bookstore-database die een database met boeken onderhoudt. Er wordt een methode weergegeven, ProcessPaperbackBookswaarmee alle paperbackboeken in de database worden gevonden en een gemachtigde voor elke boeken wordt aangeroepen. Het delegate type dat wordt gebruikt, heeft de naam ProcessBookCallback. De Test klasse gebruikt deze klasse om de titels en de gemiddelde prijs van de paperback-boeken af te drukken.

Het gebruik van gemachtigden bevordert een goede scheiding van functionaliteit tussen de bookstore-database en de clientcode. De clientcode heeft geen kennis van hoe de boeken worden opgeslagen of hoe de boekwinkelcode paperbackboeken vindt. De bookstorecode heeft geen kennis van welke verwerking wordt uitgevoerd op de paperbackboeken nadat deze zijn gevonden.

Opmerking

// 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
*/

Robuuste programmering

  • Een gemachtigde declareren.

    De volgende instructie declareert een nieuw type gemachtigde.

    public delegate void ProcessBookCallback(Book book);
    

    Elk type gemachtigde beschrijft het aantal en de typen argumenten en het type retourwaarde van methoden die kunnen worden ingekapseld. Wanneer er een nieuwe set argumenttypen of retourwaardetype nodig is, moet een nieuw gemachtigdentype worden gedeclareerd.

  • Een gemachtigde instantiëren.

    Nadat een gemachtigdentype is gedeclareerd, moet een gedelegeerde-object worden gemaakt en gekoppeld aan een bepaalde methode. In het vorige voorbeeld doet u dit door de PrintTitle methode door te geven aan de ProcessPaperbackBooks methode, zoals in het volgende voorbeeld:

    bookDB.ProcessPaperbackBooks(PrintTitle);
    

    Hiermee maakt u een nieuw gedelegeerde-object dat is gekoppeld aan de statische methode Test.PrintTitle. Op dezelfde manier wordt de niet-statische methode AddBookToTotal voor het object totaller doorgegeven zoals in het volgende voorbeeld:

    bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
    

    In beide gevallen wordt een nieuw gedelegeerde-object doorgegeven aan de ProcessPaperbackBooks methode.

    Nadat een gemachtigde is gemaakt, wordt de methode gekoppeld aan nooit wijzigingen; gedelegeerde objecten kunnen onveranderbaar zijn.

  • Een gemachtigde aanroepen.

    Nadat een gedelegeerde-object is gemaakt, wordt het gemachtigde object doorgaans doorgegeven aan andere code waarmee de gemachtigde wordt aangeroepen. Een gedelegeerde-object wordt aangeroepen met behulp van de naam van het gedelegeerde-object, gevolgd door de argumenten tussen haakjes die aan de gemachtigde moeten worden doorgegeven. Hier volgt een voorbeeld van een gemachtigde-aanroep:

    processBook(b);
    

    Een gemachtigde kan synchroon worden aangeroepen, zoals in dit voorbeeld, of asynchroon met behulp van BeginInvoke en EndInvoke methoden.

Zie ook