委托实例讲解

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Delegate
{
   
//把方法作为方法的参数,委托必须与传递的方法具有相同的参数类型和个数,通过委托动态指定要执行哪个方法
    public class Man
    {
        
private string name;
        
public Man(string name)
        {
            
this.name = name;
        }
        
public void eat(string food)
        {
            Console.WriteLine(name 
+ "" + food);
        }
    }
    
/// <summary>
    
/// 定义委托
    
/// </summary>
    
/// <param name="food"></param>
    public delegate void EatDelegate(string food);
    
public  class Program
    {
       
//params 不定参数
        static void EatToghter(string food,params EatDelegate [] values)
        {
            
if (values == null)
            {
                Console.WriteLine(
"结束!");
            }
            
else
            {
                EatDelegate eatDelegate 
= null;
                
foreach (EatDelegate ed in values)
                {
                    eatDelegate 
+= ed;
                }
                eatDelegate(food);
            }

        }

        
static void Main(string[] args)
        {
            Man zs 
= new Man("张三");
            Man ls 
= new Man("李思");
            Man ww 
= new Man("王五");
            EatDelegate _zs 
= new EatDelegate(zs.eat);
            EatDelegate _ls 
= new EatDelegate(ls.eat);
            EatDelegate _ww 
= new EatDelegate(ww.eat);
            EatDelegate eatlink 
= null;
            eatlink 
+= _zs + _ls + _ww;//+=委托链
            eatlink("橘子");
            Console.WriteLine(
"------------");
            eatlink 
-= _zs;// _=去除委托
            eatlink("西瓜");
            Console.WriteLine(
"------------");
            EatToghter(
"苹果", _zs, _ls, _ww);
            Console.WriteLine(
"------------");
            EatToghter(
"香蕉", _ls, _ww);
            EatToghter(
nullnull);
        }
    }
}

下面的示例阐释声明、实例化和使用委托。BookDB 类封装一个书店数据库,它维护一个书籍数据库。

它公开 ProcessPaperbackBooks 方法,该方法在数据库中查找所有平装书,并对每本平装书调用一个委托。

所使用的 delegate 类型称为 ProcessBookDelegate。Test 类使用该类输出平装书的书名和平均价格。

委托的使用促进了书店数据库和客户代码之间功能的良好分隔。客户代码不知道书籍的存储方式和书店代码查找平装书的方式。

书店代码也不知道找到平装书后将对平装书进行什么处理。

ContractedBlock.gif ExpandedBlockStart.gif Code
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;

namespace Bookstore
{
   

    
// 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)
                {
                    
/*创建委托对象后,通常将委托对象传递给将调用该委托的其他代码。
                    通过委托对象的名称(后面跟着要传递给委托的参数,括在括号内)调用委托对象
*/
                    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 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:
            /*明了委托类型后,必须创建委托对象并使之与特定方法关联。
            这是通过将 PrintTitle 方法传递给 ProcessPaperbackBooks 方法来完成的
*/
            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.95mtrue);
            bookDB.AddBook(
"The Unicode Standard 2.0""The Unicode Consortium"39.95mtrue);
            bookDB.AddBook(
"The MS-DOS Encyclopedia""Ray Duncan"129.95mfalse);
            bookDB.AddBook(
"Dogbert's Clues for the Clueless""Scott Adams"12.00mtrue);
        }
    }
}

转载于:https://www.cnblogs.com/hubcarl/archive/2009/05/16/1458488.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值