接口包含内容概述2——委托与事件之惑

本文详细介绍了C#中的委托和事件概念,包括委托的基本使用、多播委托以及事件的定义和使用方法。通过示例代码展示了如何创建和使用委托实例,以及如何定义和触发自定义事件。

前言:

   上篇博文《接口包含内容概述1——接口相关概述及接口中属性的实现》最后留有一疑问:一个接口为什么可以包含一个事件,却不能包含一个委托呢? 在这里要想对这个问题解答,首先必须搞清楚委托和事件这两个容易使人眩晕的问题:

 

委托概述:

   在 C 语言 的众多种类型指针中,有一种叫做“函数指针”,即是指函数的入口地址。在 C# 中委托的概念与其相类似。而与C 语言中函数指针不同的是,.NET 中的委托是类型安全的。

 

委托的使用:

     同使用一个类相类似,首先定义要使用的委托,这里规定了委托所代表的哪种类型的方法; 其次创建该委托的一个或多个实例。这里举一示范代码:

// Description: 通过建立委托实例,表现委托的定义及使用方法

// CopyRight:  http://www.cnblogs.com/yangmingming

// Notes: 为简便,将委托的定义,和验证代码放于一起

namespace  DelegateDemo
{
    
class  Program
    {
        
// 委托的定义,制定对应方法的类型
         public   delegate   int  DelegateShowInt( int  i);
        
public   static   int  ShowData( int  i)
        {
            
return  i  +   1 ;
        }


        
static   void  Main( string [] args)
        {
            DelegateShowInt showInt 
=   new  DelegateShowInt(ShowData);
            Console.WriteLine(
" The Result is {0} " , showInt( 1 ));
        }
    }
}

最后调试结果为:

 

 上例可见一般情况下,委托的应用,即在对应一个方法使用委托的情况下。

注意:

 对于式:DelegateShowInt showInt = new DelegateShowInt(ShowData) 可以认为是所有委托都有的“构造函数”形式——其参数是函数引用。

 

多播委托:

前面例子中是最为简单、常用的一种形式(一个委托实例,调用一个方法)。因为我们可以实例化一个或多个某种委托的实例,另一方面,我们也可以让一个委托调用多个方法,这里称作多播委托。

// Description: 通过建立多播委托实例,表现多播委托的定义及使用方法

// CopyRight:  http://www.cnblogs.com/yangmingming

// Notes: 为简便,将委托的定义,和验证代码放于一起

namespace  DelegateDemo
{
    
class  Program
    {
        
// 定义委托,注意返回类型为 :void
         public   delegate   void   DelegateShowInt( int  i);
        
public   static    void  ShowData( int  i)
        {
            Console.WriteLine(
" ShowData is {0} " , i);
        }
        
public   static   void   ShowData2( int  i)
        {
            Console.WriteLine (
" ShowData2 is {0} " ,i + 1 );
        }


        
static   void  Main( string [] args)
        {
            
// 多播委托的使用方法:+=
            DelegateShowInt showInt  =   new  DelegateShowInt(ShowData);
            showInt 
+= new  DelegateShowInt( ShowData2);
            showInt(
1 );
            showInt(
2 );
        }
    }
}

 而对应的调试结果为:

 

 

 通过实例,可见我们对委托对象,实现了多个方法的绑定。

注意: 之所以要求多播委托的返回类型为void,是因为如果有返回值,将没有意义,起到作用的只有最后一个被调用的函数而已!

 

事件概述:

   有了前述对委托的讲述,为这里讲解事件做好了铺垫。事件,其在Windows Form中得到极大应用,这里举一最常见的点击按钮,触发事件的例子。

 1  private   void  InitializeComponent()
 2          {
 3               this .buttonOne  =   new  System.Windows.Forms.Button();
 4               this .SuspendLayout();
 5               //  
 6               //  buttonOne
 7               //  
 8               this .buttonOne.Location  =   new  System.Drawing.Point( 241 37 );
 9               this .buttonOne.Name  =   " buttonOne " ;
10               this .buttonOne.Size  =   new  System.Drawing.Size( 75 23 );
11               this .buttonOne.TabIndex  =   0 ;
12               this .buttonOne.Text  =   " button " ;
13               this .buttonOne.UseVisualStyleBackColor  =   true ;
14               this .buttonOne.Click  +=   new  System.EventHandler( this .button_Click);
15               //  
16               //  Form1
17               //  
18               this .AutoScaleDimensions  =   new  System.Drawing.SizeF(6F, 12F);
19               this .AutoScaleMode  =  System.Windows.Forms.AutoScaleMode.Font;
20               this .ClientSize  =   new  System.Drawing.Size( 292 266 );
21               this .Controls.Add( this .buttonOne);
22               this .Name  =   " Form1 " ;
23               this .Text  =   " Form1 " ;
24               this .ResumeLayout( false );
25 
26          }

可见在14行,对对象buttonOne的事件Click赋予了委托,该委托指定了形式:

private   void  button_Click( object  sender, EventArgs e)
        {

        }

 对应类型的参数含有object和EventArgs,并且返回为void形式。这样事件就与委托相联系上。

同样可以实现不同对象的事件,对应同一委托情形:

  this .buttonOne.Click  +=   new  System.EventHandler( this .button_Click);
            
this .buttonTwo.Click  +=   new  System.EventHandler( this .button_Click);


综上可见:

1.委托,作为一种特殊的类型,雷同于定义一个类(实际上,后台即是将其作为类处理)

2.事件,规范了其类型(委托类型);

 

综上之,之所以接口不能包含委托,而接口为什么可以包含事件呢?

因为委托是一种与类同等地位的特殊类型(类的实例是存储数据的托管内存空间,而委托则只有方法地址而已),故接口不能包含委托;事件从地位上不与类、接口同一层次,事件的独特机制使得事件可以是一个接口的标准组成部分,只要继承的类包含一个public事件成员;(看样要想说明白,还要将事件讲述更清楚些,呵呵~)


附:附加版

    如上文所述,事件一般都是应用在诸如Windows form这样的事件驱动环境中。具体例子可见上述按钮触发事件自动生成的代码。然而对事件而言,我们自己也可以定义事件的,见下例:

 

 1  // Description: 通过自定义事件,了解自定义事件使用方法
 2 
 3  // CopyRight:  http://www.cnblogs.com/yangmingming
 4 
 5  // Notes: 为简便,将自定义事件的定义,和验证代码放于一起
 6 
 7 
 8  namespace  SelfDefinitionEvent
 9  {
10       // 先定义一委托类型
11       public   delegate   void  DelegateDog( );
12      
13 
14       public   class  Dog
15      {
16           // 定义事件类型,其类型对应于自定义委托类型
17           public   event  DelegateDog EventDog;
18           private   string  name;
19           public   string  Name
20          {
21               get  {  return  name; }
22               set  { name  =  value; }
23          }
24           public   void  Invoked()
25          {
26               // 使用事件方法:像使用其对应方法一样使用
27              EventDog();
28          }
29      }
30       class  Program
31      {
32           public   static   void  Response()
33          {
34              Console.WriteLine( " It will attack human. " );
35          }
36           static   void  Main( string [] args)
37          {
38              Dog dog  =   new  Dog();
39              dog.Name  =   " Jack " ;
40               // 对事件的操作,使之与对应委托相关
41              dog.EventDog  +=   new  DelegateDog(Response);
42              dog.Invoked();
43              
44          }
45      }
46  }
47 

最后结果为:

 

   

 从上例,可以看到自定义事件的从定义、赋值、使用等个部分的方法,也可以加深对事件的了解。

 

 

转载于:https://www.cnblogs.com/yangmingming/archive/2010/02/21/1670486.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值