委托

来源:互联网 发布:淘宝店铺怎么更改电话 编辑:程序博客网 时间:2024/06/09 20:09
委托
 
C#的委托一直使我非常地迷惑。虽然用.net也有一年多的时间了,一直没有真正的去理解它的原理和作用,也没有尝试着自己用代码去实现。委托的最最重要的应用就是事件和事件的处理,由于net framework对事件处理的封装处理,所以一直没有试着去搞清楚----随着开发工具的越来越傻瓜化,不知道是程序员的幸福还是悲哀。
       先来看一下msdn上对委托的定义:
委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值
简单的说,首先委托是一个类,所以它可以在定义类的任何地方定义。其次委托相当于C++中的函数指针,使得可以把方法作为参数进行传递。
对委托的实现过程的深刻理解有助于我们理解C#对事件的处理。msdn在对委托进行解释时有一段非常经典的示例代码,可以帮助我们来理解委托。
示例代码及说明:
 
// 1、书店服务器端代码
namespace Bookstore
{
    using System.Collections;
 
//声明一个结构,相当于数据库的表结构,用来放置一本书的信息。
    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.
// 声明的BookDB类相当于一个书店的数据库
//其中list -(相当于数据的表),用于存放book实例
//   AddBook方法用来维护数据库—增加书籍
 
    public class BookDB
    {
        // List of all books in the database:
       ArrayList list = new ArrayList();
 
        // 向数据库添加书籍
        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:
//在数据库中查找所有的Paperback属性为true的book,并对每一本Paperback属
//性为true的book的调用一个委托
        public void ProcessPaperbackBooks(ProcessBookDelegate processBook)
        {
            foreach (Book b in list)
            {
                if (b.Paperback)
                    // Calling the delegate:
                    processBook(b);
            }
        }
    }
}
 
// 2、书店客户端代码
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);
        }
    }
}
      
在理解了C#的委托原理后,个人觉得委托对于程序员来说(当然,我们不需要关心的对事件的处理除外)最有可能用委托来实现的功能是:组件之间的消息传递。
 
原创粉丝点击