现在的位置: 首页 > 综合 > 正文

我对委托与事件的理解

2013年09月06日 ⁄ 综合 ⁄ 共 3125字 ⁄ 字号 评论关闭

以下是我对于委托与事件的理解,如果有理解不到位的地方,请各位朋友帮忙指正,谢谢!
一、委托
1 定义
  抛开书上的意义,委托其实就是方法的代理。
  事例:比如你需要让3个人,每个人分别去做某一件事情,但此时你有这三个人的代理人(即这三个人的主管或者上司),只需要做的事情就是告诉这个代码人这三个人分别要做的事情,之后这个代理人便会自动地分别告诉这三个人应该去做什么事情。
  委托是一种类型,它可以定义在类的内部,也可以定义在类的外部,其关键字为:delegate.
2 使用
  关于委托的使用,只需要记住以下的步骤即可:
  ① 声明一个委托;
  ② 定义一个委托变量;
  ③ 为该委托变量指定其需要“代理”的方法;
  ④ 执行该委托

  事例:比如现在你有三台打印机(生活中一个人大概不会同时使用三台,此处只是做为事例说明)A,B,C,每个打印机只有一个方法,即打印,如下:

  class PrintA
    {
        public void PrintAPaint()
        {
            Console.WriteLine("A号打印机在打印");
        }
    }
        
    class PrintB
    {
        public void PrintBPaint()
        {
            Console.WriteLine("B号打印机在打印");
        }
    }
 
    class PrintC
    {
        public void PrintCPaint()
        {
            Console.WriteLine("C号打印机在打印");
        }
    }

现在你不想一台一台地操纵打印机,你想通过一个委托来帮你进行操纵,那么这时,你就要创建一个委托,我们在一个控制器中(Controller类)进行委托的相关操作,首先,你得声明一个委托,如下:

 //第一步:声明委托(注:委托其实是一种与"类"平行的概念,它可以在类的内部声明,也可以在类的外部声明,如同类一样,在使用类之前你得先创建一个类)
  public delegate void PrintPaintdelegate();

其次,你得定义一个委托变量(注:此处可以想到类,一个类在你使用的时候,首先得new一个出来,此处我们就是“new”一个委托)

 //第二步:定义委托变量
   public PrintPaintdelegate pPaintDelegate;

接下来,你得为你的委托定义添加删除方法(注:委托其实是一种代理,要想代理,需要为其提供要代理的方法)

//第三步:将想要通过委托调用的方法传递给该委托变量,可以传递给委托多个方法 
//添加方法
    public void Add(PrintPaintdelegate ppd) { pPaintDelegate += ppd; } 
//移除某个方法 
    public void Remove(PrintPaintdelegate ppd) { pPaintDelegate -= ppd; }

关于第三步,为委托添加删除方法,该方法必须与该委托的参数个数,参数类型,参数类型及返回值一样,否则编译不能通过,另外,此处的Add与Remove方法并非必须,也可以直接通过 pPaintDelegate += ppd;或pPaintDelegate -= ppd;添加删除方法,这个随大家的意愿。
  委托及相关的方法此时已经全部定义了出来,该是Main方法出场的时候了,直接上代码:

//初始化相关的变量
  PrintA pA=new PrintA();
  PrintB pB=new PrintB();
  PrintC pC=new PrintC();
      
  //定义控件器
   Controller col = new Controller();
  //为控制器添加方法
  col.Add(pA.PrintAPaint);
  col.Add(pB.PrintBPaint);
  col.Add(pC.PrintCPaint);
 
   //执行委托
   col.pPaintDelegate();
  Console.ReadLine();

在运行该程序后,输出结果如下:
  A号打印机在打印
  B号打印机在打印
  C号打印机在打印
 关于执行委托的一点说明:执行委托与执行方法的操作是一致的,有参则传参,无参则不需要参数。
最后再说一点,委托的出现就是为了事件而服务的,它的主要应用目前我知道的就是事件,所以你当你再问“委托主要是干什么用的问题”的时候,就默默地在心理回答:“它的出现就是为了事件而服务的”,:-),以上是对于委托的理解。

二、事件
事件是一种特殊的委托,关于事件的使用,与委托的使用没有太多的区别,其步骤如下:
  ① 声明一个委托;
  ② 定义一个事件变量;
  ③ 为该委托变量指定其需要“代理”的方法;
  ④ 执行该事件
事例,我们还使用刚刚定义的打印机的事件,关于打印机的具体打印方法在此处不再多说,只说一个控制器类,直接上代码:

//委托相关的操作 
//第一步:声明委托 
public delegate void PrintPaintdelegateEvent(); 
//第二步:定义事件变量 
public event PrintPaintdelegateEvent pPaintDelegateEvent; 
//第三步:将想要通过委托调用的方法传递给该委托变量,可以传递给委托多个方法 
//添加方法 
public void Add(PrintPaintdelegateEvent ppd) 
{ 
     pPaintDelegateEvent += ppd; 
} 
//移除某个方法 
public void Remove(PrintPaintdelegateEvent ppd)
 {
     pPaintDelegateEvent -= ppd; 
} 
//执行方法
 public void Run() 
{ 
    this.pPaintDelegateEvent(); 
}

注意,此处中的第二步里,在定义的委托变量时,增加了关键字,even,此为委托与事件的区别之一,再看我们的Main方法:

//初始化相关的变量 
PrintA pA = new PrintA(); 
PrintB pB = new PrintB();
 PrintC pC = new PrintC(); 
//定义控制器
 Controller col = new Controller(); 
//为控制器添加方法
 col.Add(pA.PrintAPaint);
col.Add(pB.PrintBPaint); 
col.Add(pC.PrintCPaint); 
//删除某个委托中的方法 
col.Remove(pB.PrintBPaint); 
//事件不能如委托一样在外部调用,即不能如下调用,即便该方法是Public的
 //col.pPaintDelegate();
 //只能在定义该事件的类的内部调用,代码如下:
 col.Run();
 Console.ReadLine();

在该Main方法中,与上一个委托事例中不同的地方在于,执行事件的时候,不能通过col.pPaintDelegate();执行,而只能在定义该事件的类的内部调用该事件(委托),这个是事件与委托的区别之二。
  可以这样理解,事件就是一种只能在定义该事件的类的内部执行的一种特殊的委托。
  但是此处就有另外的一个问题了,为什么事件与委托基本上一致,还要区分事件与委托呢?其实这个问题我一开始也不太清楚,后来经过查阅资料才明白,原因是这样的:
  一个委托变量,如果是pulbic的,比如上边的pPaintDelegate,可以在控制器类的内部调用,也可以在类的内部调用,但不知道大家想过没想过一个问题,如果某个人不小在该控件器类内部,初始化该类的时候,直接为该委托变量直接增加了该控制器内定义的一个私有方法,然后在main方法中执行,那么此时,该类内部的私有方法,还如何私有呢?而事件的出现,正在为了弥补这缺点的,我想大家应该明白是怎么回事了。

附代码:http://download.csdn.net/detail/hymhblf/4098735

抱歉!评论已关闭.