再谈C#委托与事件

转自:http://ruizhinet.blog.163.com/blog/static/9921382820092801032681/

之前写过一篇关于C#委托与事件的文章(见《C#委托和事件例析》),不过还是收到一些网友的提问。所以,今天再换另一个角度来详解一下这个问题。

一、在控制台下使用委托和事件

我们都知道,C#中有“接口”这个概念,所谓的“接口”就是定义一套标准,然后由实现类来具体实现其中的方法,所以说“接口,是一组类的抽象”。同样道理,我们可以将“委托”理解为“方法的抽象”,也就是说定义一个方法的模板,至于这个方法具体是怎么样的,就由方法自己去实现。

我们知道接口的最大好处就是可以实现多态,同理,“委托”是可以实现方法的多态,当我们想调用某个具体方法的时候,我们不直接调用这个方法,而是去调用这个委托。当然,我们必须在具体方法和委托之间建立某种关联。

下面我们来看例子。

首先,我们定义一个委托:

public delegate void SaySomething(string name);

这跟抽象方法的语法格式很相似,只是多了一个关键字delegate。既然是对方法的一种抽象,那么我们最关注的当然就是方法的返回值以及方法的参数了。所以上面红色的部分就是我们定义出来的一个规矩,如果某个方法想委托我去做事,那么请你遵循我的规矩,就是返回值为void,参数为一个字符串。我们这个委托的含义是,当某个人来了,就向他说点东西。

好,既然我们已经定义了这个规矩,下面我们就定义具体的方法了。

public void SayHello(string name)
{
    Console.WriteLine("Hello," + name + "!");
}


public void SayNiceToMeetYou(string name)
{
    Console.WriteLine("Nice to meet you," + name + "!");
}

我们这里一共定义了两个方法,一个是向某人说Hello,另一个是向某人说Nice to meet you。我们看到,这里定义的两个方法的返回值和参数跟我们前面定义的“委托”是一致的。

接下来,我们来看事件。

public event SaySomething come;

我们定义了一个事件,这个事件是“有人来了”,注意定义的时候我们使用event关键字,除此之外,我们还加上了前面定义的“委托”的名字。这个意思是说,我这个事件只会跟“SaySomething”打交道,并且,当我这个事件发生的时候,我会通知关注我的这些“委托”(再由这些“委托”去调用具体的方法)。

我们来定义一个测试方法:

public void test() { 
    SaySomething sayhello = new SaySomething(SayHello);
    SaySomething saynice = new SaySomething(SayNiceToMeetYou);
    come += sayhello;
    come += saynice;
    come("张三");
}

方法体中的前面两行是用来实例化委托,注意我们用到了new关键字,就好像实例化一个类一样,然后传入一个参数,但这个参数不是string类型、也不是int类型,而是一个方法名。

再下面两行就是将委托加到事件上,意思是说,如果你这个事件发生了,就告诉我一声。可以通过“+=”来将n个委托实例加到某个事件上,一旦这个事件发生,所有的这些委托实例都会得到通知。

最后一行是触发一个事件,注意我们是直接用一个事件名,然后跟一个参数,这又跟“委托”中定义的那个规矩一致(即,要有一个string类型的参数)。

最后运行一下

static void Main(string[] args)
{
    Program program = new Program();
    program.test();
    Console.Read();
}

我们回过头来再看一下“事件”的定义:

public event SaySomething come;

这里已经指出了“委托”的名字,所以,我们可以直接将方法加到事件上,而省略“委托”的实例化过程,因此上面的test()方法可以简单写为:

public void test() { 
    come += SayHello;
    come += SayNiceToMeetYou;
    come("张三");
}

 

二、在窗体中使用委托和事件

上面的例子并不能体现委托和事件的优点,其实,委托和事件在C#中使用非常广泛,例如,当我们点击某个“按钮”的时候,就会有一个“Click”事件触发,而这个事件会通知“委托”,在C#窗体应用程序中,“委托”的名字比较规范,统一使用“EventHandler”,它的具体格式是“void EventHandler(object sender, EventArgs e);”。相信大家都写过下面这样子的HelloWorld程序:

当点击按钮的时候弹出一个对话框。我们怎样实现的呢?你肯定会说,我们在设计窗口双击按钮,就会自动为我们生成类似如下的方法:

private void button1_Click(object sender, EventArgs e)
{
    MessageBox.Show("我被点击了!!!");
}

其实,这里用到的就是事件和委托,这里的button1_Click就是符合EventHandler委托规矩的一个具体的方法,即返回值为void,参数分别是一个object和EventArgs。

我们可以在Form1.Designer.cs中看到如下代码:

this.button1.Click += new System.EventHandler(this.button1_Click);

可以看到,这里有一个Click事件,然后将一个委托实例附加到这个事件上,跟我们前面讲的控制台应用程序中的用法是完全一样的。那这个Click事件是怎么触发的呢?对于这些系统类的事件,并不用我们管。

当然,我们也可以定义自己的事件和委托,例如我定义一个事件,这个事件就是输出对象的名字。

我们这里定义了一个ShowName委托和一个btnclick事件。并且,在button1_Click()方法中触发这个btnclick事件。最后的结果是,当我们点击按钮的时候,首先弹出一个“我被点击了!!!”的对话框,然后确定之后再弹出另一个显示按钮名称的对话框:

转载于:https://www.cnblogs.com/bianlan/archive/2013/01/18/2867114.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/548131.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

2021年软考中级过关

虽然分数不高,但足以证明,付出总有回报。 个人感觉在软考中级里面来讲,软件设计师历年的通过率在30%左右,根据通过率可以判断考试难度不是很大。 软件设计师考试属于软考中级资格,软件设计师比软考高级考试难度要小&…

软件工程文档

软件工程文档 文档是软件开发使用和维护当中必备的资料,文档主要是管理人员、开发人员、操作人员、用户人员之间进行协商沟通的桥梁。 1.可行性分析文档 主要是说明软件在经济上,技术上和市场情景等方面的可行性。根据这个文档,公司判断软件能…

关于map对key自定义排序

map对key默认是从小到大排序 也可以自定义排序 #include <iostream> #include <map> #include <string> // 定义自己std::map比较器 template<class _Ty> struct PLess { // functor for operator< bool operator()(const _Ty& pLef…

openssl1.1.1ARM双编译

32位的机器&#xff0c;编译法 setarch i386 ./Configure linux-generic32 no-asm shared no-async --prefix/usr/local/openssl1.1.1q CCarm-linux-gnueabihf-gcc ./ ./Configure linux-generic32 no-asm shared no-async --prefix/usr/local/openssl1.1.1q CCarm-linu…

fatal error C1010: unexpected end of file while...

为什么80%的码农都做不了架构师&#xff1f;>>> 在编译VC6.0是,出现fatal error C1010: unexpected end of file while looking for precompiled header directive 的错误. 解决方法&#xff1a; 1、如果发生错误的文件是由其他的C代码文件添加进入当前工程而引…

CMake编译 oss -cpp-sdk arm列子

一&#xff1a;声明 请用自带的交叉编译器编译&#xff0c;openssl curl也要交叉编译 1:编译arm.cmake文件 cmake_minimum_required( VERSION 2.6.3 ) if( DEFINED CMAKE_CROSSCOMPILING ) # subsequent toolchain loading is not really needed message("DEFINED CMA…

jQuery css

jQuery css模块用于css属性的修改操作。 jQuery.fn.css jQuery.fn.css function( name, value ) {//又是用access来操作return jQuery.access( this, function( elem, name, value ) {var styles, len,map {},i 0;//如果name是数组if ( jQuery.isArray( name ) ) {//通过get…

OpenGL 人物走动源码

2019独角兽企业重金招聘Python工程师标准>>> OpenGL 人物走动源码&#xff0c;记得前两天发了一个OpenGL的立方体程序&#xff0c;这个比那个厉害&#xff0c;这个是一个可以走动的小怪兽&#xff01; 转载:http://www.adobex.com/android/source/details/00000064.…

在Hyper-v中创建并安装虚拟机

1.1.1 创建并安装虚拟机 创建并安装虚拟机系统的步骤&#xff1a; 1. 点击“开始”“程序”“管理工具”“Hyper-V 管理器”。 2. 如图点击“新建”“虚拟机”。 3. 在出现的开始之前对话框&#xff0c;点击“下一步”。 4. 在指定名称和位置对话框&#xff0c;输入名称&#x…

《算法导论》读书笔记之第1章 算法在计算机中的作用

本章是本书的开篇&#xff0c;介绍了什么是算法&#xff0c;为什么要学习算法&#xff0c;算法在计算机中的地位及作用。 算法&#xff08;algorithm&#xff09;简单来说就是定义良好的计算机过程&#xff0c;它取一个或一组值作为输入&#xff0c;并产生出一个或一组值作为输…

ubuntu部署tomcat

安装版本&#xff1a;apache-tomcat-7.0.29.tar.gz&#xff08;官方网址&#xff1a;Apache Tomcat&#xff09; 安装步骤&#xff1a; 1、下载 Tomcat 下载 apache-tomcat-7.0.29.tar.gz&#xff08;官方网址&#xff09; 2、解压 Tomcat 解压 apache-tomcat-7.0.29.tar.gz ta…

android 底部菜单

2019独角兽企业重金招聘Python工程师标准>>> 新浪微薄上的一个底部菜单的实现,有兴趣的 可以看一下转载:http://www.adobex.com/android/source/details/00000118.htm 转载于:https://my.oschina.net/androidcode/blog/103835

reposurgeon 2.15 发布

reposurgeon 2.15 改成 cvs-fast-export 用于读取 RCS 和 CVS 集合&#xff0c;在效率上也有一些改进&#xff0c;并对代码进行了清理。 reposurgeon是一种工具,用于编辑版本控制存储库的历史。它允许你做一些版本控制不允许你做的操作&#xff0c;比如编辑过去的评论和元数据、…

PullToRefresh

2019独角兽企业重金招聘Python工程师标准>>> 实现下拉刷新列表内容的效果。 Code4App编译测试&#xff0c;测试环境&#xff1a;Xcode 4.3, iOS 5.0。 转载:http://www.adobex.com/ios/source/details/00000062.htm 转载于:https://my.oschina.net/u/868244/blog/10…

LYNC文件传输功能开关

LYNC如何关闭和开启文件传输功能&#xff1f;大家都知道有文件筛选的控制&#xff0c;在POWERSHELL也没有看到关闭文件传输的命令。其实这个功能在控制台上一个不显眼的位置&#xff0c;见下图&#xff1a; 此处的勾用来控制客户端上的附件图标&#xff0c;需要重新启动客户端才…

Mybatis(1)---入门篇单表查询

1.Mybatis介绍 MyBatis 是一款优秀的持久层框架&#xff0c;它支持定制化 SQL、存储过程以及高级映射。MyBatis 避免了几乎所有的 JDBC 代码和手动设置参数以及获取结果集。MyBatis 可以使用简单的 XML 或注解来配置和映射原生类型、接口和 Java 的POJO&#xff08;Plain Old …

Mybatis+Tomcat使用JNDI配置数据源入门

在我们已经有了Mybatis基础的情况下&#xff0c;我们可以使用Tomcat部署web项目1.创建Maven项目 选择webapp 2.配置pom.xml 在pom.xml中添加依赖 这里的依赖比单纯的Mybatis配置多了两个 一个是jsp的依赖&#xff0c;另一个是servlet <dependencies><dependency>&l…

Liferay开发学习Part6:Service Builder

2019独角兽企业重金招聘Python工程师标准>>> 一.什么是Service Builder&#xff1f; Service Builder是liferay IDE提供的一种代码生成方案&#xff0c;开发人员只需编辑一个数据库实体的描述文件&#xff08;XML&#xff09;,即可根据XML文件生成Spring层代码、Hib…

html+css实现响应式布局入门

什么是响应式布局 响应式布局是Ethan Marcotte在2010年5月份提出的一个概念&#xff0c;简而言之&#xff0c;就是一个网站能够兼容多个终端——而不是为每个终端做一个特定的版本。这个概念是为解决移动互联网浏览而诞生的。响应式布局可以为不同终端的用户提供更加舒适的界面…

UNIX-LINUX编程实践教程-第三章-实例代码注解-ls2

一 问题 对ls1的功能进行扩展&#xff0c;以达到类似ll命令的功能。 二 分析 在ls1中&#xff0c;我们利用readdir()函数和dirent结构体来获得目标文件夹内的文件名&#xff08;dirent->d_name&#xff09;。  现在我们借助函数stat()和结构体stat以及上面得到的文件名来获…