| C#中的委托与事件[翻译] |
|
| 作者:未知 文章来源:mx68.com收集 点击数: 更新时间:2006-1-19 15:40:31
|
委托与事件 Ganesh Nataraj最近写了一篇解释委托与事件的文章,在坊间流传较广,今天翻译成中文与大家共享,如有不妥之处,欢迎留言讨论。 C#中的委托类似于C或C++中的函数指针。程序设计人员可以使用委托将方法的引用压缩到委托对象中,委托对象能被传递给调用该方法引用的代码而无须知道哪个方法将在编译时被调用。与C或C++中的指针不同的是,委托是面向对象的、类型安全的、受保护的。 委托声明时定义一个返回压缩方法的类型,其中包含一组特定的描述和返回类型。对于静态方法而言,委托对象压缩其调用的方法。对于实例方法(instance methods)而言,委托对象将压缩一个实例和实例的一个方法。如果一个委托对象有一组适当的描述,可以调用带描述的委托。 委托有趣而实用的一个特征就是它不用知道也无需关心它引用对象的类,任何对象都可以,关键的是方法的描述类型和引用类型要与委托的匹配。这使委托特别适合一些匿名的请求。 注意:委托以调用方的安全许可身份运行,而不是以声明方的许可运行。 下面有两个委托的示例: 例1向大家说明如何声明、实例化和调用一个委托; 例2向大家说明如何联合两个委托。 例1 这个例子说明如何声明、实例化和使用委托。BookDB类压缩了一个包含各种书籍的书店数据库,它对外暴露ProcessPaperbackBooks方法,用以查找数据库中所有平装本的书籍并调用委托,使用委托来调用ProcessBookDelegate。Test类使用这个类来打印处平装本书籍的标题和平均价格。 委托的使用促进了书店数据库与客户端代码之间功能性的良好分离。客户端代码不用知晓书是如何存的如何找到平装本,而书店的代码不用知道查找到该平装书并提供给客户端后将会被如何处理。代码如下(为了部影响理解,代码保持原样): 1// bookstore.cs 2using System; 3// A set of classes for handling a bookstore: 4namespace Bookstore 5{ 6 using System.Collections; 7 // Describes a book in the book list: 8 public struct Book 9 { 10 public string Title; // Title of the book. 11 public string Author; // Author of the book. 12 public decimal Price; // Price of the book. 13 public bool Paperback; // Is it paperback? 14 public Book(string title, string author, decimal price, bool paperBack) 15 { 16 Title = title; 17 Author = author; 18 Price = price; 19 Paperback = paperBack; 20 } 21 } 22 23 // Declare a delegate type for processing a book: 24 public delegate void ProcessBookDelegate(Book book); 25 26 // Maintains a book database. 27 public class BookDB 28 { 29 // List of all books in the database: 30 ArrayList list = new ArrayList(); 31 32 // Add a book to the database: 33 public void AddBook(string title, string author, decimal price, bool paperBack) 34 { 35 list.Add(new Book(title, author, price, paperBack)); 36 } 37 38 // Call a passed-in delegate on each paperback book to process it: 39 public void ProcessPaperbackBooks(ProcessBookDelegate processBook) 40 { 41 foreach (Book b in list) 42 { 43 if (b.Paperback) 44 45 // Calling the delegate: 46 processBook(b); 47 } 48 } 49 } 50} 51// Using the Bookstore classes: 52namespace BookTestClient 53{ 54 using Bookstore; 55 56 // Class to total and average prices of books: 57 class PriceTotaller 58 { 59 int countBooks = 0; 60 decimal priceBooks = 0.0m; 61 internal void AddBookToTotal(Book book) 62 { 63 countBooks += 1; 64 priceBooks += book.Price; 65 } 66 internal decimal AveragePrice() 67 { 68 return priceBooks / countBooks; 69 } 70 } 71 // Class to test the book database: 72 class Test 73 { 74 // Print the title of the book. 75 static void PrintTitle(Book b) 76 { 77 Console.WriteLine(" {0}", b.Title); 78 } 79 // Execution starts here. 80 static void Main() 81 { 82 BookDB bookDB = new BookDB(); 83 // Initialize the database with some books: 84 AddBooks(bookDB); 85 // Print all the titles of paperbacks: 86 Console.WriteLine("Paperback Book Titles:"); 87 // Create a new delegate object associated with the static 88 // method Test.PrintTitle: 89 bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(PrintTitle)); 90 // Get the average price of a paperback by using 91 // a PriceTotaller object: 92 PriceTotaller totaller = new PriceTotaller(); 93 // Create a new delegate object associated with the nonstatic 94 // method AddBookToTotal on the object totaller: 95 bookDB.ProcessPaperbackBooks(new ProcessBookDelegate(totaller.AddBookToTotal)); 96 Console.WriteLine("Average Paperback Book Price: ${0:#.##}", 97
[1] [2] 下一页
|
|
[ 收藏此页到: 天天|和讯|博采|ViVi|狐摘|我摘|天极 ] 文章录入:admin 责任编辑:admin |
|
上一篇文章: C# Google PageRank .net库 (checksum) 下一篇文章: C#中从HTML生成DOM TreeView的代码 |
| 【字体:小 大】【发表评论】【加入收藏】【告诉好友】【打印此文】【关闭窗口】 |