This example shows how to combine multicast delegates. One purpose of the delegate object is that it can be used+Operators assign them to a delegated instance to be a multicast delegate. The combination of the two delegates can be called. Only delegates of the same type can be combined.
-The operator can be used to remove a component delegate from the delegate of a combination.
Example
Delegate Void Del ( String S );
Class Testclass
{
Static Void Hello ( String S)
{
System. Console. writeline ( " Hello, {0 }! " , S );
}
Static Void Goodbye ( String S)
{
System. Console. writeline ( " Goodbye, {0 }! " , S );
}
Static Void Main ()
{
Del a, B, c, d;
// Create the delegate object a that references
// The method Hello:
A = Hello;
// Create the delegate object B that references
// The method goodbye:
B = goodbye;
// The two delegates, A and B, are composed to Form C:
C = A + B;
// Remove a from the composed delegate, leaving D,
// Which callonly the method goodbye:
D = C-;
System. Console. writeline ( " Invoking delegate: " );
A ( " A " );
System. Console. writeline ( " Invoking Delegate B: " );
B ( " B " );
System. Console. writeline ( " Invoking delegate C: " );
C (" C " );
System. Console. writeline ( " Invoking delegate D: " );
D ( " D " );
}
}
/* Output:
Invoking delegate:
Hello,!
Invoking Delegate B:
Goodbye, B!
Invoking delegate C:
Hello, C!
Goodbye, C!
Invoking delegate D:
Goodbye, D!
*/
Use of delegation:
In C #1.0 and later versions, you can declare the delegate as follows:
Public Delegate VoidDel <t> (T item );
Public VoidNotify (IntI ){}
Del <Int> D1 =NewDel <Int> (Notify );
In C #2.0 and later versions, you can use the following simplified syntax to declare and initialize the delegate using an anonymous method:
Del <Int> D2 = 127y;
In C #3.0 and later versions, you can also use lambda expressions to declare and instantiate delegates. For more information, seeLambda expressions (C # programming guide).
The following example illustrates the declaration, instantiation, and use of delegation.BookdbClass encapsulates a bookstore database, which maintains a Book database. It is publicProcesspaperbackbooksThis method searches for all the books in the database and calls a delegate for each book. UsedDelegateType nameProcessbookdelegate.TestClass uses this class to print the title and average price of the books on the Assembly.
Delegated use promotes bookstore databases and customersCodeGood separation between functions. The Customer Code does not know how books are stored or how the bookstore code looks for books on a regular basis. The bookstore Code does not know what to do with the book after it finds it.
Important delegate usageExample:
// 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 );
// 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.0 m ;
Internal Void Addbooktototal (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 = 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. addbook ( " The C Programming Language " , " Brian W. kernighan and Dennis M. Ritchie " , 19.95 m , True );
Bookdb. addbook ( " The Unicode standards 2.0 " , " The Unicode Consortium " , 39.95 m , True );
Bookdb. addbook ( " The MS-DOS encyclopedia " , " Ray Duncan " , 129.95 m , False );
Bookdb. addbook ( " Dogbert's clues for the clueless " , " Scott Adams " , 12.00 m , True );
}
}
}
/* Output:
Paperback book titles:
The C Programming Language
The Unicode standards 2.0
Dogbert's clues for the clueless
Average paperback book price: $23.97
*/
Reliable Programming
-
Declare the delegate.
The following statement declares a new delegate type.
Public Delegate VoidProcessbookdelegate (Book );
Each delegate type describes the number and type of parameters, as well as the return type of the methods it can encapsulate. Each time a new set of parameter types or return value types are required, a new delegate type must be declared.
Instantiate the delegate.
After declaring the delegate type, you must create a delegate object and associate it with a specific method. In the previous examplePrinttitleMethod passedProcesspaperbackbooksMethod to achieve this:
Bookdb. processpaperbackbooks (printtitle );
This will create static methodsTest. printtitleAssociated with the new delegate object. Similarly, the objectTotallerNon-static methodAddbooktototalIs passed in the following example:
Bookdb. processpaperbackbooks (totaller. addbooktototal );
In both examplesProcesspaperbackbooksMethod to pass a new delegate object.
After a delegate is created, its associated methods cannot be changed; the delegate object cannot be changed.
-
Call the delegate.
After a delegate object is created, it is usually passed to other code that calls the delegate. The delegate object is called by the name of the delegate object (followed by the parameter to be passed to the delegate, which is enclosed in brackets. The following is an example of a delegated call:
Processbook (B );
As in this example, you can useBegininvokeAndEndinvokeMethod synchronous or asynchronous call delegate.