日斋
日新月异
首先让我们先了解一下什么是回调函数
回调函数
1、什么是回调函数?
答:简单的说,回调函数是一个通过函数指针调用的函数

2、为什么我们要使用回调函数?
答:调用者(Button类)并不关心被调用者是谁;它所知道的是具有特定原型的被调用者(定义在主程序中的MyBtnClick方法)以及一些可能的限制(比如,返回值可以是整数,不过特定的值有特定含义)
举例:
如 果你想知道实践中回调函数多有用,想象一下你想写一个排序算法实现的库(的确很经典),比如冒泡排序,希尔排序,shake排序,快速排序等等。关注点在 于为了是你的库更加通用,你不想嵌入排序逻辑(一个数组内两个元素之间哪一个在前)到你的函数中。你想让客户决定哪一种逻辑。或者说,你想让库对各种数据 类型都有用(int,floats,strings) 等等。因此,你应该怎样做?你会使用函数指针并且利用回调。
总结:就是你写的函数让系统来调用
委托+事件    

    在系统事件中,如鼠标或键盘按下,发送器就是.NET运行库(假设点了Button一下,那发送器就是Button).注意,事件的发送器并不知道接收器是谁,这就使得事件非常用用.
    事件可以使用多播委托,但是不能保证调用方法的前后顺序.
    事件处理方法不能有返回值.只要使用EventHandler委托就必须使用objectEventArtgs参数. 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、事件总是委托类型的,这个委托类型的签名定义了处理该事件的方法的签名;(myClick)
3、定义事件处理程序方法的对象称事件接收方(就是主程序此例为MyClass);
4、事件接收方提供的事件处理方法必须与该事件预订的方法签名一致. (godBtnClick)
5、在事件的通信中,事件发送者不知道哪个对象或方法将要去接收/发送事件,因而在事件源和事件接收者之间就需要一个中间人-委托;
6、当指派多个处理程序给一个事件的时候,处理程序的调用次序是没有保证的.(多播委托)
7EventHandler 是一个用于事件的委托,它有两个参数objectEventArg,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)定义响应函数 publicvoid OnmyClick()
5)调用响应函数,响应函数调用触发函数,事件被触发了 mc.OnmyClick();
:在系统定义的响应事件中,4) 5)步是不可见的.
posted on 2010-01-11 14:38  李承隆  阅读(831)  评论(0编辑  收藏  举报