黑马程序员技术交流社区

标题: C#中的委托是什么?事件是不是一种委托? [打印本页]

作者: duanhuilin    时间: 2012-11-7 14:27
标题: C#中的委托是什么?事件是不是一种委托?
一、了解委托
      我们知道回调函数实际上就是方法调用的指针,也就是通常所说的函数指针。那么在.NET中,以委托的方式来实现了函数指针的概念。.NET中使用委托的主要原因是它是类型安全的,为什么呢?因为在以前,比如C中,函数指针只不过是一个指向存储单元的指针,我们无法说出这个指针实际指向什么,而委托确定了指向方法的返回值类型和参数列表。注意的是:委托并不等同于方法,而是一个引用类型。

一、委托的定义
委 //第1步:声明一个委托
        public delegate void CalculateDelegate(int x, int y);

        //第2步:创建与委托关联的方法,二者具有相同的返回值类型和参数列表
        public void Add(int i, int j)
        {
            MessageBox.Show((i+j).ToString());
        }

        //第3步:定义委托类型变量
        private CalculateDelegate myDelegate;

        public void GetDelegateEx()
        {
            //第4步:进行委托绑定
            myDelegate = new CalculateDelegate(Add);

            //第5步:回调Add方法
            myDelegate(1, 2);
        }


作者: 李栋Jelly    时间: 2012-11-7 15:01
委托
委托是一个类,它定义了方法的类型,使得可以将方法当作另一个方法的参数来进行传递,
这种将方法动态地赋给参数的做法,可以避免在程序中大量使用If-Else(Switch)语句,同时使得程序具有更好的可扩展性。
委托可以认为是包含具有相同签名和返回值的有序方法列表,当委托被调用时,它调用列表中的每个方法
委托类型声明以delegate关键词开头,没有方法主体

委托声明方法
delegate void MyDel(int x);

事件
事件就好像被简化的针对特殊用途的委托
事件接受类型的返回值与委托匹配的事件处理程序
事件不是成员,不能使用对象创建表达式(new)来创建他们
由于事件不是成员: 必须声明在类或结构中,和其他成员一样   不能在一段可执行代码中声明事件
事件成员被隐式自动转化为null
        private  event MyDel myE;  
        public event MyDel MyE
        {
            add { myE += value; }
            remove { myE -= value; }
        }

例如:
老鼠无聊想玩游戏,他就得将要玩游戏的时间通知给耗子,然后由耗子来执行老鼠所要做的事
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;

  5. namespace Csharp面向对象_事件练习
  6. {
  7.     /// <summary>
  8.     /// 类PlayEventArgs 必须继承自类EventArgs,用来引发事件时封装数据
  9.     /// </summary>
  10.     public class PlayEventArgs : EventArgs
  11.     {
  12.         public String Play; //游戏名称名称
  13.         public decimal moneyOut; //准备消费金额
  14.     }

  15.     /// <summary>
  16.     /// 这个委托用来说明处理玩游戏事件的方法的方法头(模式)
  17.     /// </summary>
  18.     public delegate void PlayEventHandler(object sender, PlayEventArgs e);

  19.     /// <summary>
  20.     /// 引发玩游戏事件(PlayEvent)的类Master(主人),这个类必须
  21.     /// 1.声明一个名为PlayEvent的事件: public event PlayEventHandler PlayEvent;
  22.     /// 2.通过一个名为OnPlayEvent的方法来引发吃饭事件,给那些处理此事件的方法传数据;
  23.     /// 3.说明在某种情形下引发事件呢?在想玩游戏的时候。用方法PalyDota来模拟。
  24.     /// </summary>
  25.     public class Master
  26.     {
  27.         //声明事件
  28.         public event PlayEventHandler PalyEvent;

  29.         //引发事件的方法
  30.         public void OnPlayEvent(PlayEventArgs e)
  31.         {
  32.             if (PalyEvent != null)
  33.             {
  34.                 PalyEvent(this, e);
  35.             }
  36.         }

  37.         //当主人想玩游戏的时候,他会指定所玩游戏和消费金额。
  38.         public void PlayDota(String restrauntName, decimal moneyOut)
  39.         {
  40.             PlayEventArgs e = new PlayEventArgs();
  41.             e.Play = restrauntName;
  42.             e.moneyOut = moneyOut;

  43.             Console.WriteLine("主人说:");
  44.             Console.WriteLine("我无聊,要去玩{0},消费{1}元", e.Play, e.moneyOut);

  45.             //引发事件  
  46.             OnPlayEvent(e);
  47.         }
  48.     }

  49.     /// <summary>
  50.     /// 类Servant(仆人)有一个方法Arrange(安排)来处理主人的玩游戏事件
  51.     /// </summary>
  52.     public class Servant
  53.     {
  54.         public void Arrange(object sender, PlayEventArgs e)
  55.         {
  56.             Console.WriteLine();
  57.             Console.WriteLine("耗子说:");
  58.             Console.WriteLine("您的命令是 : ");
  59.             Console.WriteLine("要玩的游戏 -- {0}", e.Play);
  60.             Console.WriteLine("准备消费 -- {0}元 ", e.moneyOut);
  61.             Console.WriteLine("好的,正给您安排。。。。。。。。\n");
  62.             System.Threading.Thread.Sleep(5000);//系统等待时间 5秒
  63.             Console.WriteLine("您的日程已经安排");
  64.         }
  65.     }

  66.     /// <summary>
  67.     /// 类God安排mouse的仆人是hz,并让hz的Arrange
  68.     /// 方法来处理mouse的吃饭事件:mouse.PlayEvent += new PlayEventHandler(hz.Arrange);
  69.     /// </summary>
  70.     public class God
  71.     {
  72.         public static void Main(String[] args)
  73.         {
  74.             Master mouse = new Master();
  75.             Servant hz = new Servant();

  76.             mouse.PalyEvent += new PlayEventHandler(hz.Arrange);

  77.             //老鼠想玩游戏,要玩Dota,准备消费50元
  78.             mouse.PlayDota("Dota", 50.0m);
  79.             Console.ReadKey();
  80.         }
  81.     }
  82. }
复制代码





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2