c#中的delegate(委托)和event(事件)

一、delegate是什么东西?

完全可以把delegate理解成C中的函数指针,它允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作参数传递。不过delegate和函数指针还是有点区别的,delegate有许多函数指针不具备的优点。首先,函数指针只能指向静态函数,而delegate既可以引用静态函数,又可以引用非静态成员函数。在引 用非静态成员函数时,delegate不但保存了对此函数入口指针的引用,而且还保存了调用此函数的类实例的引用。其次,与函数指针相 比,delegate是面向对象、类型安全、可靠的受控(managed)对象。也就是说,runtime能够保证delegate指向一个有效的方法, 你无须担心delegate会指向无效地址或者越界地址。

举例来说明

例一:

public class DelegateTest
{
// 声明delegate对象
public delegate void CompareDelegate(int a,int b);
// 欲传递的方法,它与CompareDelegate具有相同的参数和返回值类型
public static void Compare(int a,int b)
{
Console.WriteLine((a>b).ToString());
} public static void Main()
{
// 创建delegate对象
CompareDelegate cd = new CompareDelegate(DelegateTest.Compare);
// 调用delegate
cd(1,2);
}
}

例二:

public delegate void MyTestDelegate(int i);
public class Program
{
public static void Main()
{
//创建delegate
ReceiveDelegateArgsFunc(new MyTestDelegate(DelegateFunction));
}
//这个方法接收一个delegate类型的参数,也就是接收一个函数作为参数
public static void ReceiveDelegateArgsFunc(MyTestDelegate func)
{
func(21);
}
//欲传递的方法
public static void DelegateFunction(int i)
{
System.Console.WriteLine("传过来的参数为: {0}.", i);
}
}

二、event(事件),onclick的由来

C#中的事件处理实际上是一种具有特殊签名的delegate,象下面这个样子:

public delegate void MyEventHandler(object sender, MyEventArgs e);

其中的两个参数,sender代表事件发送者,e是事件参数类。MyEventArgs类用来包含与事件相关的数据,所有的事件参数类都必须从 System.EventArgs类派生。当然,如果你的事件不含参数,那么可以直接用System.EventArgs类作为参数。

好了,咱们就以OnClick为例说说事件的实现吧。

//这里自定义一个EventArgs,因为我想知道Clicker
public class ButtonClickArgs : EventArgs
{
public string Clicker;
} public class MyButton
{
//定义一个delegate委托
public delegate void ClickHandler(object sender, ButtonClickArgs e);
//定义事件,类型为上面定义的ClickHandler委托
public event ClickHandler OnClick; public void Click()
{
//...触发之前可能做了n多操作
//..... //这时触发Click事件,并传入参数Clicker为本博主ivy
OnClick(this, new ButtonClickArgs() { Clicker = "ivy" });
}
} public class Program
{
public static void Main()
{
MyButton btn = new MyButton(); //注册事件,把btn_OnClick方法压入事件队列,
//可以+=多个,这里简单点就压入一个吧。
btn.OnClick += new MyButton.ClickHandler(btn_OnClick);
} //怎么看到这个函数很熟悉吧,就是你原来双击button自动产生的代码
public static void btn_OnClick(object sender, ButtonClickArgs e)
{
Console.WriteLine("真贱,我居然被ivy点击了!");
}

button的点击事件:

btn.OnClick += new MyButton.ClickHandler(btn_OnClick);

好梦。

c#中的delegate(委托)和event(事件)的更多相关文章

  1. .NET进阶篇-语言章-2-Delegate委托、Event事件

    知识只有经过整理才能形成技能 整个章节分布简介请查看第一篇 内容目录 一.概述 二.解析委托知识点 1.委托本质 2.委托的使用 3.委托意义 逻辑解耦,减少重复代码 代码封装支持扩展 匿名方法和La ...

  2. Python 中Semaphore 信号量对象、Event事件、Condition

    Semaphore 信号量对象 信号量是一个更高级的锁机制.信号量内部有一个计数器而不像锁对象内部有锁标识,而且只有当占用信号量的线程数超过信号量时线程才阻塞.这允许了多个线程可以同时访问相同的代码区 ...

  3. C#中的委托 Delegate(委托 也叫代表,代表一类方法)

    1. 委托类似与 C或C++中的函数指针,但委托是 面向对象的,并且是类型安全的 详情可查看官方文档:https://msdn.microsoft.com/en-us/library/ms173172 ...

  4. 线程中的samaphore信号量及event事件

    一.信号量 samaphore: 在程序中意思为同时允许几个线程运行,比如我们去水上乐园的滑梯玩时,有四个滑梯,每一个滑梯上当没有人在中间玩滑下去时才允许上人,四个滑梯1,2,3,4,同时最多四个人, ...

  5. 终于会用c#中的delegate(委托)和event(事件)了

    一.开篇忏悔 对自己最拿手的编程语言C#,我想对你说声对不起,因为我到现在为止才明白c#中的delegate和event是怎么用的,惭愧那.好了,那今天就趁月黑风高的夜晚简单来谈谈delegate和e ...

  6. 终于会用c#中的delegate(委托)和event(事件)了 [转]

    原文 : http://www.cnblogs.com/zhangchenliang/archive/2012/09/19/2694430.html 一.开篇忏悔 对自己最拿手的编程语言C#,我想对你 ...

  7. 对于新手用c#中的delegate(委托)和event(事件)

    一.delegate到底是什么东西 delegate允许你传递一个类A的方法m给另一个类B的对象,使得类B的对象能够调用这个方法m,说白了就是可以把方法当作参数传递.delegate既可以引用静态函数 ...

  8. 看看可爱c#中的delegate(委托)和event(事件)用法好不好

    一.开篇忏悔 对自己最拿手的编程语言C#,我想对你说声对不起,因为我到现在为止才明白c#中的delegate和event是怎么用的,惭愧那.好了,那今天就趁月黑风高的夜晚简单来谈谈delegate和e ...

  9. C#中的委托(Delegate)和事件(Event)

    原文地址:C#中的委托(Delegate)和事件(Event) 作者:jiyuan51 把C#中的委托(Delegate)和事件(Event)放到现在讲是有目的的:给下次写的设计模式--观察者(Obs ...

随机推荐

  1. 关于Extjs使用window.opener报错

    项目中使用window.opener 刷新父窗口表格,父窗口表格IE8报错, window.opener.Ext.getCmp('SalesCompanyGridPanel').getStore(). ...

  2. .Net 组件技术概述

    1. 基本原理 组件是组件系统中功能的表现,没有组件就没有功能.特定接口是用于给组件管理程序来操纵.管理该组件,特定功能是组件需要完成的任务.在一个使用组件建立的产品中会随着功能数目的多少而会有多个组 ...

  3. 使用c#生成Identicon图片

    Identicon是什么 我们在站点注册的时候通常系统会在我们没有提供自定义头像时为我们指定一个默认的头像,不过,样子千篇一律很是难看.聪明的程序员想了很多办法来解决这个问题,比如你能在这里看到很漂亮 ...

  4. 在centos7中限制kvm虚拟机可访问的资源

    最近通过艰苦卓绝的度娘(我很想用谷歌,可是,你懂的),终于搞明白如何在centos7中限制kvm虚拟机可访问的资源了.度娘给出的结果中,大部分都说的很对,然而,却很难照着做,主要原因有两点:1.网上的 ...

  5. 常用终端及git命令

    终端常用命令 1,打开终端,git version 查看版本 2,pwd 打印工作目录 3,ls(list简写)查看当前目录的所有文件 4,clear 清掉屏幕 5,cd (change direct ...

  6. bzoj2748:[HAOI2012]音量调节

    思路:刷水有益健康. #include<iostream> #include<cstdio> #include<cstring> #include<algor ...

  7. 1.MySQL的安装(linux Ubuntu环境下)

    首先先检验一下系统中是否已经安装有mysql: deamon@deamon-H55M-S2:~$ sudo netstat -tap | grep mysql [sudo] password for ...

  8. [翻译]log4net教程

    原文:log4net Tutorial 一.基础: log4net分为三部分:配置.设置和调用.配置通常是在app.webconfig或web.config文件中:为了增加灵活性,我们也可以使用单独的 ...

  9. 【转】WPF获取外部EXE图标最简单的方法

    首先在工程添加对System.Drawing的引用 创建以下方法: public static ImageSource GetIcon(string fileName) { System.Drawin ...

  10. 更改git bash默认的路径

    更改git bash默认的路径   在打开git bash时,每次都是在C:\Uer路径下,每次都需要先用cd命令转换到自己需要工作的路径(cd  /f/dss).修改打开git bash 时的默认的 ...