Gewusst wie: Deklarieren, Instanziieren und Verwenden von Delegaten (C#-Programmierhandbuch)How to: Declare, Instantiate, and Use a Delegate (C# Programming Guide)

In C# 1.0 und höher können Delegaten wie im folgenden Beispiel gezeigt deklariert werden.In C# 1.0 and later, delegates can be declared as shown in the following example.

// 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 bietet eine einfachere Möglichkeit zum Schreiben der vorangegangenen Deklaration, siehe folgendes Beispiel.C# 2.0 provides a simpler way to write the previous declaration, as shown in the following example.

// C# 2.0 provides a simpler way to declare an instance of Del.
Del del2 = Notify;

In C# 2.0 und höher ist es außerdem möglich, eine anonyme Methode zum Deklarieren und Initialisieren eines Delegaten zu verwenden. Dies wird im nachstehenden Beispiel gezeigt.In C# 2.0 and later, it is also possible to use an anonymous method to declare and initialize a delegate, as shown in the following example.

// Instantiate Del by using an anonymous method.
Del del3 = delegate(string name)
    { Console.WriteLine("Notification received for: {0}", name); };

In C# 3.0 und höher können Delegaten auch mithilfe eines Lamdaausdrucks deklariert und instanziiert werden, wie im folgenden Beispiel dargestellt.In C# 3.0 and later, delegates can also be declared and instantiated by using a lambda expression, as shown in the following example.

// Instantiate Del by using a lambda expression.
Del del4 = name =>  { Console.WriteLine("Notification received for: {0}", name); };

Weitere Informationen finden Sie unter Lambdaausdrücke.For more information, see Lambda Expressions.

Im folgenden Beispiel wird verdeutlicht, wie Sie einen Delegaten deklarieren, instanziieren und verwenden.The following example illustrates declaring, instantiating, and using a delegate. In der BookDB-Klasse ist eine Buchhandlungsdatenbank gekapselt, die eine Buchtiteldatenbank enthält.The BookDB class encapsulates a bookstore database that maintains a database of books. Sie stellt eine ProcessPaperbackBooks-Methode zur Verfügung, durch die alle Taschenbücher in der Datenbank gefunden werden und für jedes Taschenbuch ein Delegat aufgerufen wird.It exposes a method, ProcessPaperbackBooks, which finds all paperback books in the database and calls a delegate for each one. Der verwendete delegate-Typ hat den Namen ProcessBookDelegate.The delegate type that is used is named ProcessBookDelegate. Die Test-Klasse verwendet diese Klasse, um die Buchtitel und Durchschnittspreise der Taschenbücher auszugeben.The Test class uses this class to print the titles and average price of the paperback books.

Die Verwendung von Delegaten beinhaltet eine sinnvolle Trennung der Funktionalitäten von Buchhandlungsdatenbank und Clientcode.The use of delegates promotes good separation of functionality between the bookstore database and the client code. Der Clientcode hat keine Kenntnis darüber, wie die Bücher archiviert werden oder wie der Buchhandlungscode Taschenbücher sucht.The client code has no knowledge of how the books are stored or how the bookstore code finds paperback books. Der Buchhandlungscode wiederum hat keine Kenntnis darüber, wie ein Taschenbuchtitel weiterverarbeitet wird, nachdem er gefunden wurde.The bookstore code has no knowledge of what processing is performed on the paperback books after it finds them.

BeispielExample

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

Stabile ProgrammierungRobust Programming

  • Deklarieren von DelegatenDeclaring a delegate.

    Mit der folgenden Anweisung wird ein neuer Delegattyp deklariert.The following statement declares a new delegate type.

    public delegate void ProcessBookDelegate(Book book);
    

    Durch die einzelnen Delegattypen werden Anzahl und Typen von Argumenten sowie Rückgabewerte von Methoden beschrieben, die gekapselt werden können.Each delegate type describes the number and types of the arguments, and the type of the return value of methods that it can encapsulate. Sobald neue Argumenttypen benötigt werden oder ein neuer Rückgabewerttyp erforderlich ist, muss ein neuer Delegattyp deklariert werden.Whenever a new set of argument types or return value type is needed, a new delegate type must be declared.

  • Instanziieren von DelegatenInstantiating a delegate.

    Nachdem ein Delegattyp deklariert wurde, muss ein Delegatobjekt erstellt und einer bestimmten Methode zugeordnet werden.After a delegate type has been declared, a delegate object must be created and associated with a particular method. Im vorherigen Beispiel übergeben Sie dazu die PrintTitle-Methode an die ProcessPaperbackBooks-Methode, wie im folgenden Beispiel gezeigt:In the previous example, you do this by passing the PrintTitle method to the ProcessPaperbackBooks method as in the following example:

    bookDB.ProcessPaperbackBooks(PrintTitle);
    

    Hierdurch wird ein neues Delegatobjekt erstellt, das der statischen Methode Test.PrintTitle zugeordnet ist.This creates a new delegate object associated with the static method Test.PrintTitle. Auf ähnliche Weise wird die nicht statische Methode AddBookToTotal für das Objekt totaller übergeben, wie im folgenden Beispiel gezeigt:Similarly, the non-static method AddBookToTotal on the object totaller is passed as in the following example:

    bookDB.ProcessPaperbackBooks(totaller.AddBookToTotal);
    

    In beiden Fällen wird ein neues Delegatobjekt an die ProcessPaperbackBooks-Methode übergeben.In both cases a new delegate object is passed to the ProcessPaperbackBooks method.

    Nach der Erstellung eines Delegaten wird die diesem zugeordnete Methode nicht mehr geändert. Delegatobjekte sind unveränderlich.After a delegate is created, the method it is associated with never changes; delegate objects are immutable.

  • Aufrufen von DelegatenCalling a delegate.

    Nachdem ein Delegatobjekt erstellt wurde, wird es normalerweise an anderen Code übergeben, durch den der Delegat aufgerufen wird.After a delegate object is created, the delegate object is typically passed to other code that will call the delegate. Ein Delegatobjekt wird über seinen Namen aufgerufen. Auf den Namen folgen (in Klammern gesetzte) Argumente, die an den Delegaten übergeben werden sollen.A delegate object is called by using the name of the delegate object, followed by the parenthesized arguments to be passed to the delegate. Es folgt ein Beispiel für einen Delegataufruf:Following is an example of a delegate call:

    processBook(b);
    

    Ein Delegat kann entweder (wie in diesem Beispiel) synchron oder mithilfe der BeginInvoke-Methode und der EndInvoke-Methode asynchron aufgerufen werden.A delegate can be either called synchronously, as in this example, or asynchronously by using BeginInvoke and EndInvoke methods.

Siehe auchSee Also

C#-ProgrammierhandbuchC# Programming Guide
EreignisseEvents
DelegatenDelegates