Delegate (Delegate)

Source: Internet
Author: User
Tags bool expression interface new set
A delegate in C # is similar to a function pointer in C or C + +. Using delegates enables programmers to encapsulate method references within a delegate object. You can then pass the delegate object to code that can invoke the referenced method without having to know at compile time which method will be invoked. Unlike function pointers in C or C + +, delegates are object-oriented, type-safe, and secure.

A delegate declaration defines a type that encapsulates a method with a specific set of parameters and a return type. For static methods, the delegate object encapsulates the method to invoke. For instance methods, the delegate object encapsulates both an instance and a method on that instance. If you have a delegate object and a set of appropriate parameters, you can invoke the delegate with these parameters.

An interesting and useful attribute of a delegate is that it does not know or care about the class of the object it references. Any object can be, except that the parameter type and return type of the method must match the delegate's parameter type and the return type. This makes the delegate perfect for anonymous calls.

This tutorial includes two examples:

Example 1 shows how to declare, instantiate, and invoke a delegate.

Example 2 shows how to combine two delegates.

In addition, the following topics are discussed:

Delegates and events

Delegates and interfaces

Example 1

The following example illustrates declaring, instantiating, and using delegates. The Bookdb class encapsulates a bookstore database that maintains a book database. It exposes the ProcessPaperbackBooks method, which finds all the paperback books in the database and invokes a delegate for each book. The type of delegate used is called Processbookdelegate. The Test class uses this class to output the title and average price of the paperback book.

The use of delegates facilitates a good separation of functionality between the bookstore database and the customer code. Customer code does not know how books are stored and how bookstores code looks for paperback books. The bookstore code does not know what to do with the paperback after you find a paperback book.

Bookstore.cs

Using System;



A set of classes for handling a bookstore:

Namespace Bookstore

{

Using System.Collections;

Describes a book list:

public struct book

{

public string Title; Title of the book.

public string Author; Author of the book.

public decimal price; Price is 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 Test

{

Print the title of the book.

static void PrintTitle (book B)

{

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:

Console.WriteLine ("Paperback Book Titles:");

Create a new delegate object associated with the static

Method Test.PrintTitle:

Bookdb.processpaperbackbooks (New Processbookdelegate (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 (New Processbookdelegate (Totaller). AddBookToTotal));

Console.WriteLine ("Average paperback book Price: ${0:#.##}",

Totaller. Averageprice ());

}

Initialize The book database and 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

Code Discussion

The declaration delegates the following statement:

public delegate void Processbookdelegate (book book);

Declares a new delegate type. Each delegate type describes the number and type of parameters, and the return value type of the method that it can encapsulate. You must declare a new delegate type whenever you need a new set of parameter types or a new return value type.

After an instantiated delegate declares a delegate type, you must create the delegate object and associate it with a specific method. Similar to all other objects, the new delegate object is created with an expression. When you create a delegate, however, the arguments passed to the new expression are special: It is written like a method call, but there is no parameter to the method.

The following statement:

Bookdb.processpaperbackbooks (New Processbookdelegate (PrintTitle));

Creates a new delegate object that is associated with a static method Test.PrintTitle. The following statement:

Bookdb.processpaperbackbooks (New

Processbookdelegate (Totaller. AddBookToTotal));

Creates a new delegate object that is associated with a non-static method AddBookToTotal on an object totaller. In two examples, the new delegate object is immediately passed to the ProcessPaperbackBooks method.

Note that once a delegate is created, the method it is associated with will never change: The delegate object cannot be changed.

When a delegate is created by a call, a delegate object is typically passed to the other code that will invoke the delegate. The delegate object is invoked by the name of the delegate object (followed by the arguments to be passed to the delegate, enclosed in parentheses). The following is an example of a delegate invocation:

Processbook (b);

Example 2

This example demonstrates a combined delegate. A useful attribute of a delegate object is that they can be combined by the "+" operator. The combined delegate calls the two delegates that compose it in turn. Only delegates of the same type can be grouped, and the delegate type must have a void return value. The "-" operator can be used to remove a component delegate from a grouped delegate.

Compose.cs

Using System;

delegate void MyDelegate (string s);

Class MyClass

{

public static void Hello (string s)

{

Console.WriteLine ("Hello, {0}!", s);

}

public static void Goodbye (string s)

{

Console.WriteLine ("Goodbye, {0}!", s);

}

public static void Main ()

{

MyDelegate A, B, C, D;

Create the delegate object A that references

The method Hello:

A = new MyDelegate (Hello);

Create The delegate object B that references

The method Goodbye:

b = new MyDelegate (Goodbye);

The two delegates, A and B, are composed to form C,

Which calls both methods in order:

c = a + B;

Remove A from the composed delegate, leaving D,

Which calls only the method Goodbye:

D = c-a;

Console.WriteLine ("Invoking delegate A:");

A ("a");

Console.WriteLine ("Invoking Delegate B:");

B ("B");

Console.WriteLine ("Invoking delegate C:");

C ("C");

Console.WriteLine ("Invoking Delegate D:");

D ("D");

}

}

Output

Invoking delegate A:

Hello, A!

Invoking Delegate B:

Goodbye, B!

Invoking Delegate C:

Hello, C!

Goodbye, C!

Invoking Delegate D:

Goodbye, D!

Delegates and events

A delegate is ideal for use as an event (notifies a "listener" of changes in the component from a component).

Delegates and interfaces

The similarities between delegates and interfaces are that they allow for the separation of specifications and implementations. Multiple independent authors can generate multiple implementations that are compatible with an interface specification. Similarly, delegates specify the signature of a method, and multiple authors can write multiple methods that are compatible with the delegate specification. When should the interface be used, and when should the delegate be used?

Delegates are useful in the following situations:

Call a single method.

A class might want to have multiple implementations of a method specification.

You want to allow the specification to be implemented using static methods.

Want to design patterns for similar events.

The caller does not need to know or get the object on which the method is defined.

The implemented provider wants to implement the "distribute" specification only for a few selected components.

A convenient combination is required.

Interfaces are useful in the following situations:

The specification defines a set of related methods that will be invoked.

A class typically implements only the specification once.

The caller of the interface wants to convert to an interface type or from an interface type to obtain another interface or class.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.