[C#] - 委托 事件 回调函数

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

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

    在系统事件中 , 如鼠标或键盘按下 , 发送器就是 .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) 步是不可见的 .

转载于:https://www.cnblogs.com/lcl_1015/articles/1644097.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值