模拟现实的一个问题:
比如说有一个公司(场景),你是老板,手下有主管和员工,作为老板你会指派(委托)主管管理员工的工作,如果某个员工玩游戏,则让某个主管从该员工的薪水里扣去500元钱。这就是现实中的委托。而在写程序中,假设程序员就是老板,有两个类分别为主管和员工,而主管小王和员工小张就是两个类的对象实例。员工类有一个方法:玩游戏,同时就有一个玩游戏的事件,他一玩游戏就会激发这个事件。而主管类就是负责处理该事件的,他负责把玩游戏的员工的薪水扣除500。使用委托与事件触发的程序如下:
//ExWebDelegate2.cs
using System;
public delegate void PlayGameHandler(object sender,EventArgs e);
public class Manager
{
public Manager()
{
Console.WriteLine("生成主管");
}
public void SubMoney(object sender,EventArgs e)
{
Console.WriteLine("主管:好小子,上班时间胆敢玩游戏?");
Console.WriteLine("主管:看看你小子有多少薪水");
Employee  employee=(Employee)sender;
Console.WriteLine("开始扣薪水...");
System.Threading.Thread.Sleep(5000);
employee.Money=employee.Money-500;
Console.WriteLine("扣薪水执行完毕");
}
}
public class Employee
{
public event PlayGameHandler PlayGame;
private int money;
public Employee()
{
Console.WriteLine("生成员工");
money=1000;
}
public int Money
{
get
{
return money;
}
set
{
money=value;
}
}
public void PlayingGame()
{
Console.WriteLine("员工开始玩游戏了");
Console.WriteLine("员工:CS真好玩,哈哈,我玩...");
System.Threading.Thread.Sleep(5000);
EventArgs e=new EventArgs();
OnPlayGame(e);
}
protected virtual void OnPlayGame(EventArgs e)
{
if (PlayGame!=null)
{
PlayGame(this,e);
}
}
}
public class ExWebDelegate2
{
public static void Main()
{
Console.WriteLine("场景开始了");
Manager wang=new Manager();
Employee zhang=new Employee();
zhang.PlayGame+=new PlayGameHandler(wang.SubMoney);//zhang.PlayGame是事件
/*
 * 当PlayGame事件产生时,就会调用Manager类的SubMoney方法
 * */
Console.WriteLine("该员工原本有的薪水:"+zhang.Money.ToString());
zhang.PlayingGame();
Console.WriteLine("现在该员工还剩下:"+zhang.Money.ToString());
Console.WriteLine("场景结束");
Console.ReadLine();
}
}
请高手们能帮我分析一下委托与事件触发吗?谢谢了!~

解决方案 »

  1.   

    写这个程序的人真无聊,而且多多少少歪曲了“委托”的意思
    身为程序员,还是应该用程序员的角度描述问题“委托”,delegate,其实我觉得翻译成“代表”还好一点,它“代表”一个样子跟他差不多的方法。例如有以下方法:private int DoSomething(string s) {...}和以下委托(还是入乡随俗吧,我也叫委托好了):public delegate int DoThingsDelegate(string s);那么,因为样子差不多(术语叫“特征”(signature)相同——参数列表和返回值一样),这个委托就可以“代表”上面的方法。具体的“代表”的方法是:private DoThingsDelegate varDoThingsDelegate; // 定义委托变量
    varDoThingsDelegate = new DoThingsDelegate(DoSomething) // 将方法与委托连接起来
    int returnValue = varDoThingsDelegate("hello!"); // 使用委托调用被代表的方法以上三步缺一不可,但是第二步通常都不是我们自己做的——如果我们自己已经知道了方法名字,为什么不直接调用方法呢?我们通常都是1)定义委托,2)定义委托变量,3)让别人对委托变量赋值,4)把委托变量看成是个方法来调用。这就推断出委托的使用场合:当我们要调用某个方法,但是我们只知道这个方法该长什么样子而不知道具体从哪里获得的时候,就是使用委托的时候。.NET 里,有两个地方最常使用委托,首先就是事件,不过这个等下再说,然后就是异步调用方法。异步调用方法,简而言之,就是叫一个对象“开始”一项工作,但不需要立刻返回结果,我也不等待结果,继续我自己的工作,到这个对象“完成”,可以返回结果的时候再“告诉我”。整个故事的难点就是“告诉我”——这个对象怎么才能知道该怎么告诉我?为此,我在叫它“开始”工作的时候,顺便把我的一个方法包装成委托,告诉它“做完了之后,用这个方法告诉我”。这样,工作对象就不需要知道我是谁/什么,完成工作之后尽管调用委托就行了。事件摆在异步之后说,是因为事件是一种特殊的委托——可以“代表”多个同特征方法的委托。考虑以下场景:雇员wang有一个PlayGame事件,雇员li交给wang一个委托,说“你玩游戏的时候告诉我”,然后雇员zhang也交给wang另一个委托:“你玩游戏的时候也告诉我”。那么,雇员wang必须找个方法将所有玩游戏委托都记住,以便通知所有人,以免三缺一。这种“多播委托”(MulticastDelegate)是事件的基本模型,在事件发生的时候由事件触发者通过调用委托来运行未知位置未知名字但已知特征的多个方法。使用事件跟使用委托有一些区别。首先,符合委托特征的方法有了新名字:事件处理器(event handler),因为它的作用就是处理一个事件。然后,将委托交给事件所有者这个动作叫做“订阅”(subscribe),也就是说事件像周刊一样,发行的时候你就能收到一份。使用事件的步骤是//1, 定义委托。该委托必须无返回(void),
    //   因为事件如果存在多个订阅者,有返回值就乱套了。
    //   委托类型的名字习惯用EventHandler或Handler结束,
    //   因为这个委托类型代表的是事件处理器。
    public delegate void PlayGameEventHandler(Employee starter, string gameName);
    // public delegate void 委托类型名(参数列表);//2,在对象里定义事件,即“委托变量”——多播委托变量
    public event PlayGameEventHandler PlayGame;
    // public event 委托类型名 事件名;//3,由其他对象操作,订阅事件
    wang.PlayGame += new PlayGameEventHandler(this.wang_PlayGame);
    // 取消订阅只需要将上面的 += 改成 -=// 这个是事件处理器的范例:
    private void wang_PlayGame(Employee starter, string gameName)
    { Console.Write("我也要玩" + gameName + "!!"); }//4,事件发生时,调用所有订阅者的事件处理器:
    if (this.PlayGame != null) // 没有人订阅就会 == null
        this.PlayGame(this, "Tic Tac Toe");===================
    我不是专业程序员,但我学编程很久了,虽然应用层面的知识不够CSDN里的强人,但是我有的是耐心和细心。要找我去我论坛,gamesir.enorth.com.cn/Forum-191.html,我天天都去的。
      

  2.   

    lz举的例子一开始学习委托与事件也看过,这个例子写的不好理解,我也写过,lz可以看看,http://blog.csdn.net/lyb_abiandbel/archive/2005/10/20/510034.aspx
    我纯粹是从语法角度理解的。
    不过我觉得委托的重要之处就是象 netmicro(麦)所说,除了事件,那就是异步调用。不过网友还是认为lz举的例子形象。
      

  3.   

    netmicro(麦)兄讲的不是很深。但很清楚、明白。谢谢了。也谢谢楼主的提问。希望大家一起进步。
      

  4.   

    如果方法相当于一个动词,委托相当于一个动名词
    class 人类
    {
        //构造函数代码略
        public void 好()
    }
    //分别new 一个人类的实例:我、他 (代码略 )public void delegate 好(); 好 他好=new 好(他.好)
    好 我好=new 好(我.好)
    好 大家好=他好+我好嘿嘿,汇仁肾保:)