作者:TomMax (笑望人生)     出处:csdn 主  题: “.net百题问答的活动”--许多人问过的--《 C#委托及事件 》所属论坛: .NET技术 C#有许多人问的,.Net中的委托以及事件处理。我拿简单的例子说明一下,是现实中的例子:比如说一个公司(场景),你是老板,手下有两个员工,小张和小王。你命令小王,如果小张玩游戏,则小王扣去小张500元钱。这就是现实中的委托。
实际上,在写程序中,程序员就是老板,小张和小王就是两个对象。小张玩游戏是一个方法,小张还有一个游戏事件,他玩游戏激发这个事件。而小王就是事件处理对象,他负责把小张的钱扣除500。所以,委托有如下几个要素:1 激发事件的对象--就是小张2 处理对象事件的对象--就是小王3 定义委托,就是你让小王监视小张。如果这三个要素都满足的话,则你就写出了一个完整事件的处理。
下面有个例子:在vs.net2003 C#控制台应用程序编辑运行成功:using System;namespace CSharpConsole
{    public class 场景
    {
        [STAThread]
        public static void Main(string[] args)
        {
            Console.WriteLine("场景开始了....");            // 生成小王            小王 w = new 小王();            // 生成小账            小张 z = new 小张();            // 指定监视            z.PlayGame += new PlayGameHandler(w.扣钱);            // 开始玩游戏            z.玩游戏();            console.writeline("场景结束...");            Console.ReadLine();        }    }    // 负责扣钱的人    public class 小王
    {        public 小王()
        {            Console.WriteLine("生成小王...");        }        public void 扣钱(object sender, EventArgs e)
        {            Console.WriteLine("小王:好小子,上班时间胆敢玩游戏...");            Console.WriteLine("小王:看看你小子有多少钱...");            小张 f = (小张)sender;            Console.WriteLine("小张的钱: " + f.钱.ToString());            Console.WriteLine("开始扣钱......");            System.Threading.Thread.Sleep(500);            f.钱 = f.钱 - 500;            Console.WriteLine("扣完了....现在小张还剩下:" + f.钱.ToString());        }    }    // 如果玩游戏,则引发事件    public class 小张
    {        // 先定义一个事件,这个事件表示“小张”在玩游戏。        public event PlayGameHandler PlayGame;        // 保存小张钱的变量        private int m_Money;        public 小张()
        {            Console.WriteLine("生成小张....");            m_Money = 1000; // 构造函数,初始化小张的钱。        }        public int 钱 // 此属性可以操作小张的钱。
        {            get
            {                return m_Money;            }            set
            {                m_Money = value;            }        }        public void 玩游戏()
        {            Console.WriteLine("小张开始玩游戏了.....");            Console.WriteLine("小张:CS好玩,哈哈哈! 我玩.....");            System.Threading.Thread.Sleep(500);            System.EventArgs e = new EventArgs();            OnPlayGame(e);        }        protected virtual void OnPlayGame(EventArgs e)
        {            if (PlayGame != null)
            {                PlayGame(this, e);            }        }    }    // 定义委托处理程序    public delegate void PlayGameHandler(object sender, System.EventArgs e);}
很早之前自己的学习资料,今天无意中发出来了,就分享给和我一样的初学者吧

解决方案 »

  1.   

    oj是我在.Net板块最佩服的了。
    你做.Net这块多久了?
      

  2.   

     这是我整理出来的源代码
    using System;
     class PubEventArgs : EventArgs
     {
      private readonly string m_magazineName;
      private readonly DateTime m_pubDate;
      public PubEventArgs(string magazineName,DateTime pubDate)
      {
      m_magazineName = magazineName;
      m_pubDate = pubDate;
      }
      public string magazineName
      {
      get{return m_magazineName;}
      }
      public DateTime pubDate
      {
      get {return m_pubDate;}
      }
     }
     class Publisher // 出版社
     {
      public delegate void PubComputerEventHandler(object sender,PubEventArgs e);//声明事件所需的代理
      public delegate void PubLifeEventHandler(object sender,PubEventArgs e);
      public event PubComputerEventHandler PubComputer;//事件的声明
      public event PubLifeEventHandler PubLife;
      protected virtual void OnPubComputer(PubEventArgs e)
      {
      PubComputerEventHandler handler = PubComputer;
      if(handler !=null)
      {
      handler(this,e);
      }
      }
      protected virtual void OnPubLife(PubEventArgs e)
      {
      PubLifeEventHandler handler = PubLife;
      if(handler !=null)
      {
      handler(this,e);
      }
      }
      public void issueComputer(string magazineName,DateTime pubDate)//触发事件的方法
      {
      Console.WriteLine("发行"+ magazineName);
      OnPubComputer(new PubEventArgs(magazineName,pubDate));
      }
      public void issueLife(string magazineName,DateTime pubDate)//触发事件的方法
      {
      Console.WriteLine("发行"+ magazineName);
      OnPubLife(new PubEventArgs(magazineName,pubDate));
      }
     }
     class Subscriber //订阅者
     {
      private string name;
      public Subscriber(string name)
      {
      this.name = name;
      }
      public void Receive(object sender,PubEventArgs e)//在事件订阅者中定义事件处理程序
      {
      Console.WriteLine(e.pubDate+""+name+"已经收到"+e.magazineName);
      }
     }
     class Story
     {
      static void Main()
      {
      Publisher Pub = new Publisher();
      Subscriber zs = new Subscriber("张三");
      Pub.PubComputer += new Publisher.PubComputerEventHandler(zs.Receive);//向事件发行者订阅一个事件
      Subscriber ls = new Subscriber("李四");
      Pub.PubComputer += new Publisher.PubComputerEventHandler(ls.Receive);
      Pub.PubLife += new Publisher.PubLifeEventHandler(ls.Receive);
      Pub.issueComputer("电脑杂志",Convert.ToDateTime("2008-1-1"));//触发事件
      Pub.issueLife("生活杂志",Convert.ToDateTime("2008-1-1"));
      Console.WriteLine();
      Console.WriteLine("一年后");
      Pub.PubComputer -= new Publisher.PubComputerEventHandler(ls.Receive);
      Pub.issueComputer("电脑杂志",Convert.ToDateTime("2009-1-1"));//触发事件
      Pub.issueLife("生活杂志",Convert.ToDateTime("2009-1-1"));
      }
     }
      

  3.   


    当某段代码,在不同的环境需要不同的写法时就可以用委托来处理。比如:
    Array.ConvertAll<>
    Array.ForEach<>
    之类的
      

  4.   

    看了别人的一个委托例子    class Test
        {
            static void Main(string[] args)
            {
                t n = new t();
                n.我店里是卖商品的(n.a);//客人来买商品a
                
            }
        }
        delegate void 我是帮老板调用商品的();
        class t
        {
            public void a()
            {
                Console.WriteLine("我是商品a");
            }
            public void b()
            {
                Console.WriteLine("我是商品b");
            }
            public void 我店里是卖商品的(我是帮老板调用商品的 m)
            {
                m();
            }
        }
      

  5.   

    3 定义委托,就是你让小王监视小张。 和委托行为是恰恰相反,你说让小王监视小张,那对于小王,这是主动行为,而委托应该是被动行为你的代码中也可以看出: OnPlayGame(e); 对于小张来说,这是主动行为,对于小王来说,这是被动的。
    这相当于,小张在告诉大家“我在玩游戏”,那谁会对这行为感兴趣?
    小张也不知道,所以要定义一个事件 public event PlayGameHandler PlayGame; 
    谁感兴趣谁添加一个事件就可以了,事件处理函数的原型呢?就是 public delegate void PlayGameHandler(object sender, System.EventArgs e); 
    事件是委托使用比较广泛的例子,你这帖子主要是在说事件吧委托就是定义一个新类型,使用委托和使用类型都差不多一样使用 string 类型声明一个方法void go(string arg)
    {
    if(arg != null) ....
    }使用委托类行也一样,只不过还可以当方法调用一下void go(Handler arg)
    {
    if(arg != null) arg("abcd")
    }上面 Handler 的定义类似于 delegate void Handler(string p); 
      

  6.   

    这种写法跟C++里面的消息传递,调用函数基本上是一样的吧?Class 小王
    {
    private PlayGames()
    {
    SendMessage(hwnd,PLAY_GAME,0,0);
    }
    }Class 小王
    {
    ON_MESSAGE(PLAY_GAME, &小王::OnPlayGame)public OnPlayGame()
    {
    罚钱();
    }
    }