前言:

上篇博文《接口包含内容概述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

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

  1. 事件委托(事件代理)概述

    事件委托(事件代理)概述 什么是事件委托(事件代理) 事件委托(事件代理)是基于Js冒泡原理,把本来加在子元素身上的事件,加在了其父级身上. 通过event对象里记录的"事件源", ...

  2. C#委托与事件学习笔记

    今天跟随视频学习了一下C#中最重要的一些概念之委托与事件.老杨的视频讲的还是挺深入浅出,不过刚接触C#.NET的人还是朦朦胧胧,就像张子阳先生说的"每次见到委托和事件就觉得心里别(biè)得 ...

  3. C#基础加强(8)之委托和事件

    委托 简介 委托是一种可以声明出指向方法的变量的数据类型. 声明委托的方式 格式: delegate <返回值类型> 委托类型名(参数) ,例如: delegate void MyDel( ...

  4. C# 概念 委托和事件

    源码下载:http://www.tracefact.net/SourceCode/Delegates-and-Events-in-CSharp.rar C# 中的委托和事件 引言 委托 和 事件在 . ...

  5. 脑机接口BCI技术概述

    脑机接口BCI技术概述 前言 一.脑机接口BCI是什么? 二.BCI的框架 1 信号采集 2 信号处理 2.1 预处理 2.2 特征提取 2.3 模式分类 3 BCI应用 三. 脑控系统中常用的BCI ...

  6. [C#]委托和事件(讲解的非常不错)

    引言 委托 和 事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去 ...

  7. js中的事件委托或是事件代理详解(转载)

    起因: 1.这是前端面试的经典题型,要去找工作的小伙伴看看还是有帮助的: 2.其实我一直都没弄明白,写这个一是为了备忘,二是给其他的知其然不知其所以然的小伙伴们以参考: 概述: 那什么叫事件委托呢?它 ...

  8. C# 关于委托和事件的妙文:通过一个例子详细介绍委托和事件的作用;Observer模式简介...

    委托和事件在 .Net Framework中的应用非常广泛,然而,较好地理解委托和事件对很多接触C#时间不长的人来说并不容易.它们就像是一道槛儿,过了这个槛的人,觉得真是太容易了,而没有过去的人每次见 ...

  9. 委托与事件代码详解与(Object sender,EventArgs e)详解

    委托与事件代码详解 using System; using System.Collections.Generic; using System.Text; namespace @Delegate //自 ...

最新文章

  1. 移动网站性能优化(未完。。。)
  2. Coding-字符串
  3. 因一个计算机故障而“停工”!观测宇宙 30 多年的哈勃太空望远镜还能坚持多久?...
  4. utf编码在线转换工具
  5. 读写锁ReadWriteLock和缓存实例
  6. MySQL第12天:MySQL索引优化分析之性能优化案例实践
  7. FormData的使用
  8. 产品经理高质量产物的五步思维法
  9. vue和react的区别是什么?
  10. 线性模型第2讲:岭回归与分类
  11. DCMTK 关键配置
  12. pe擦除服务器硬盘,怎么彻底删除硬盘数据
  13. 给定一个正整数n,输出如下n*n之字形方阵
  14. 学会Redis缓存中间件,这一篇就够了
  15. 在Web前端基于CAD图实现等值线在线分析
  16. Windows命令行查看文件的MD5 和win10下获取md5-sha1
  17. Spring boot开发小而美的个人博客
  18. 基于tensorflow2的手写中文数字识别(自己创建数据集)
  19. SSH整合过程中遇到的头秃问题
  20. java计算两个日期间隔天数

热门文章

  1. 什么是单页应用(转)
  2. softmax函数上溢出和下溢出(转载+自己理解)
  3. ubuntu下面解决mysqld_safe Directory '/var/run/mysqld' for UNIX socket file don't exists
  4. python2.7删除所有非utf-8编码的字符串
  5. OpenGL中的上下文 理解整理
  6. 根据文法画出语法树_编译工程5:语法分析(3)
  7. 基本的JVM内存分配过程案例
  8. Mysql的命令行操作
  9. React总结篇之六_React高阶组件
  10. 中国航天将与人工智能技术携手 未来可期