首先让我们先了解一下什么是回调函数
回调函数
1、什么是回调函数?
答:简单的说,
回调函数是一个通过函数指针调用的函数
。
2、为什么我们要使用回调函数?
答:调用者(
Button类
)并不关心被调用者是谁;它所知道的是具有特定原型的被调用者(定义在主程序中的MyBtnClick方法)以及一些可能的限制(比如,返回值可以是整数,不过特定的值有特定含义)
举例
:
如果你想知道实践中回调函数多有用,想象一下你想写一个排序算法实现的库(的确很经典),比如冒泡排序,希尔排序,shake排序,快速排序等等。关注点在于为了是你的库更加通用,你不想嵌入排序逻辑(一个数组内两个元素之间哪一个在前)到你的函数中。你想让客户决定哪一种逻辑。或者说,你想让库对各种数据类型都有用(int,floats,strings) 等等。因此,你应该怎样做?你会使用函数指针并且利用回调。
总结
:
就是你写的函数让系统来调用
委托+事件
事件(C#高级编程笔记)
在系统事件中
,
如鼠标或键盘按下
,
发送器就是
.NET
运行库
(
假设点了
Button
一下
,
那发送器就是
Button
类
).
注意
,
事件的发送器并不知道接收器是谁
,
这就使得事件非常用用
.
事件可以使用多播委托
,
但是
不能保证
调用方法的前后
顺序
.
事件处理方法
不能有返回值
.
只要使用
EventHandler
委托就
必须使用
object
和
EventArtgs
参数
. object
是引发事件的
对象
, EventArtgs
包含有关事件的有用的
信息
.
事件定义:
事件触发者(如Button类)定义了一个函数指针(如下例中的委托myClick),这个函数指针可以在以后指向某个处理事件函数.当事件发生时,调用该函数指针指向处理函数,并将事件的上下文作为参数传入.处理完成后,控制权将被事件触发者回收.
自我理解
:
问
:
为什么事件要用委托实现
?
答
:
就拿一个标准
Button
来说
,
当你点下去之后
,
会发生的内容在哪儿定义
?
如果你进入到
Button
类里定义
,
好
,Button
已经被比尔这家伙封装了
,
你可进不去
,
进去了也不能修改
;
咋办昵
?????
算了
,Button
哭着对
主程序
(
假设当前主程序是一个
Win Form)
说
,
你做我的代理
,
帮我完成吧
.
由此
,
Button
将它的
Click
事件委托给了主程序
.
这下你可以在
Form
里为所欲为了
,
让它干什么
,
它就得干什么
?(Button:"
主程序,你是禽兽
...
";
主程序:"哇哈哈哈,这可由不得你啦...(屏幕漆黑中...)"
)
网友理解
:
1、委托就是代理
.
如果你是厂商,假如要你直接去卖你的产品,那你将面对的是所有的消费者
.
假如你依靠代理卖你的产品,那你将面对的仅仅是各个省或地区的代理。
2、委托是一种特殊的类型(class),用途是来实现对一种方法的封装,在某种事件发生时,自动调用该方法。好处显然易见,它使用户可以
自定义自己的方法实现(
就是前面所说的为所欲为
)
,通过封装,CLR会在相应事件激发时调用你定义的方法,实现你的功能。
3、认为是函数指针的是C/C++程序员,理解基本正确,但有一点,委托可以是"成员函数的指针"。认为是类的,没错,.NET里什么都是类,委托类包含了一个对象(o)和对象中一个方法(m)的信息,实现了调用这个方法(o.m())的方法(委托的调用)。说用委托来实现类的组合,这个观点不敢苟同。类的组合应该是两个完整的类,如果通过委托把一个类的部分方法和其它类组合应该是不完全的。
using
System;
using
System.Collections.Generic;
public
class
MyClass
...
{
public static void Main()
...{
MyClass mc = new MyClass();
myButton godBtn = new myButton();
godBtn.myClick += new EventHandler(mc.godBtnClick);
godBtn.OnmyClick();
Console.ReadLine();
}
public void godBtnClick(object sender,EventArgs e)
...{
Console.WriteLine("on my god...button");
}
}
public
class
myButton
...
{
public event EventHandler myClick; //一个委托事件 myClick
protected void OnmyClick() //注意,最好使用protected修饰符,以便只给继承它的类使用
...{
if(myClick != null)
...{
myClick(this,new EventArgs());
}
}
}
定义实现一个事件的流程
1
、引发事件的对象称
事件源
;
2
、事件总是委托类型的
,
这个委托类型的签名定义了处理该事件的方法的签名
;(
如my
Click)
3
、定义事件处理程序方法的对象称
事件接收方(就是主程序此例为MyClass)
;
4
、事件接收方提供的事件处理方法必须与该事件预订的方法签名一致
. (
如godBtnClick)
5
、在事件的通信中
,
事件发送者不知道哪个对象或方法将要去接收
/
发送事件
,
因而在事件源和事件接收者之间就需要一个中间人
-
委托
;
6
、当指派多个处理程序给一个事件的时候
,
处理程序的调用次序是没有保证的
.(多播委托
)
7
、
EventHandler
是一个用于事件的委托
,
它有两个参数
object
和
EventArg,object
代表了事件的发送者
,EventArg
对象代表了事件包含的数据
;
8
、所以有事件处理方法都可以使用
EventHandler,
但你也可以使用
EventHandler
的子类
.(
如
public event PaintEventHandler Paint;
其实
PaintEventHandler
是
EventHandler
的子类
)
1)
定义事件
(
变量
)
public
event
EventHandler myClick;
2)
定义事件方法
public
static
void
godBtnClick(
object
sender, EventArgs e);
3)
将事件与事件方法相关联
mc.myClick+=
new
EventHandler(godBtnClick);
//EventHandler
是一个委托,委托通常把方法当参数传递,
btnGetClick
是一个方法
4)
定义响应函数
public
void
OnmyClick()
5)
调用响应函数
,
响应函数调用触发函数
,
事件被触发了
mc.OnmyClick();
注
:
在系统定义的响应事件中
,
第
4) 5)
步是不可见的
.