Делегат - это обеспечивающий типовую безопасность объект, указывающий на другой метод или методы, которые могут быть вызваны с помощью делегата позже. Тип делегата хранит три следующих элемента информации:
Делегат способен вызывать свои методы синхронно или асинхронно.
Чтобы создать делегат нужно использовать ключевое слово delegate. Имя делегата может быть любым. Делегат должен соответствовать методу, на который он будет указывать. Типы параметров и тип возврата должны либо совпадать с объявлением делегата, либо быть неявно преобразуемыми в типы, указанные в объявлении делегата.
Объявление делегата:
public delegate double ProcessResult(double x, double y);)
Чтобы добавить целевой метод в делегат, нужно просто передать имя этого метода конструктору делегата. Тогда можно вызвать указанный член с помощью синтаксической конструкции, подобной прямому вызову функции. Делегаты могут указывать, как на статические методы, так и на методы экземпляров. В точке вызова делегата синтаксис идентичен и не зависит от того, указывает ли делегат на метод экземпляра или статический метод.
Простейший пример делегата
namespace SimpleDelegate { // Этот делегат может указывать на любой метод, принимающий два целых значения и возвращающий целое значение. public delegate int BinaryOp(int x, int y); // Этот класс содержит методы, на которые будет указывать BinaryOp. public class SimpleMath { public static int Add(int x, int y) { return x+y; } public static int Subtract(int x, int y) { return x-y; } } class Program { static viod Main(string[] args) { Console.WriteLine("Пример делегата \n"); // Создание объекта BinaryOp, указывающего на SimpleMath.Add(). BinaryOp b = new BinaryOp(SimpleMath.Add); // Вызов метода Add() с помощью делегата. Console.WriteLine("10+10 равно {0}", b(10,10)); Console.ReadLine(); } } }
Цепочка делегатов позволяет создавать связанный список делегатов, так что когда вызывается делегат, находящийся в начале списка, вслед за ним выполняются все делегаты цепочки.
Примеры.Примеры взяты из примеров
Microsoft поставляемых с VS2008.
Пример файл проекта Delegates1. Мной
внесены только стилистические изменения.
- //Copyright (C) Microsoft Corporation. All rights reserved.
-
- // bookstore.cs
- using System;
-
- // 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 Test
- {
- // Print the title of the book.
- static void PrintTitle(Book b)
- {
- Console.WriteLine(" {0}", b.Title);
- Console.WriteLine();
- }
-
- // 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 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);
- }
- }
- }
* This source code was highlighted with Source Code Highlighter.