当前位置: 首页 > news >正文

.NET 回调、接口回调、 委托

回调浅析(委托、接口回调)
说到C#回调,通常情况下,指的是某个委托或者接口回调。现将从网上各位前辈那里学得的一些经验加以整理,形成一个稍全面一些的文章,希望对大家有所帮助!
一、 委托
先看一段代码:
// 定义委托
delegate void WorkDone();

class Program
{
static void Main(string[] args)
{
Do();

	Console.ReadLine();
}

public static void Do()
{
	// 首先给callback委托赋值
	WorkDone callback = new WorkDone(WorkDoneHandler);
	// 将callback作为参数
	Working(callback);
}

public static void Working(WorkDone callBack)
{
	// 当工作完成的时候执行这个委托
	callBack();
}

public static void WorkDoneHandler()
{
	Console.WriteLine(DateTime.Now);
}

}

上面的代码中,将方法WorkDoneHandler()作为参数,传递给了另一个方法Working(WorkDone callBack),这样做的好处在于,可以动态的指定执行哪个方法。比如在Do()方法中,我们指定的callback 是WorkDoneHandler 当然也可以是其它匹配的方法。而Working()方法根本不需要知道自己最后执行的是哪个Handler。
二、 接口回调
通常情况下,我们创建一个对象,并马上直接去使用它的方法。然而,在有些情况下,希望能在某个场景出现后或条件满足时才调用此对象的方法。回调就可以解决这个“延迟调用对象方法”的问题。这个被调用方法的对象称为回调对象。
实现回调的原理简介如下:
首先创建一个回调对象,然后再创建一个控制器对象,将回调对象需要被调用的方法告诉控制器对象。控制器对象负责检查某个场景是否出现或某个条件是否满足。当此场景出现或此条件满足时,自动调用回调对象的方法。

以下为C#实现回调的一个小例子:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
//创建一个控制器对象,将提供给它的回调对象传入
Controller obj = new Controller(new CallBack());
//启动
obj.Star();
}
}
public interface IBack
{
void run();
}
public class CallBack : IBack
{
public void run()
{
//为了简洁这里只是显示下时间
System.Console.WriteLine(DateTime.Now);
}
}
public class Controller
{
public IBack CallBackObj = null; //这里引用回调对象
public Controller(IBack obj)
{
this.CallBackObj = obj;
}
public void Star()
{
Console.WriteLine(“敲键盘任意键就显示当前的时间,直到按ESC退出…”);
while (Console.ReadKey(true).Key != ConsoleKey.Escape)
{
CallBackObj.run();
}
}
}
}
可以看到,当示例程序运行时,何时调用CallBack对象的run()方法是由用户决定的,用户每敲一个键,控制器对象就调用一次CallBack的run()方法。这个示例中实现回凋的关键在于IBack接口的引入。

 如果不用IBack接口,而直接使用 CallBack对象,一样可以实现同样的效果,如下: 
   public class Controller 
 { 
     public CallBack CallBackObj = null;   //回调对象方法的引用 
     public Controller(CallBack obj) 
     { 
         this.CallBackObj = obj; 
     } 
     public void Star() 
     { 
         Console.WriteLine("敲键盘任意键就显示当前的时间,直到按ESC退出...."); 
         while (Console.ReadKey(true).Key != ConsoleKey.Escape) 
         { 
             CallBackObj.run(); 
         } 
     } 
 } 

但仔细思考,这样做的结果就使Controller类与CallBack对象绑定在一起,万一如果需要调用其他类型的对象,则必须修改Controller类的代码。
如果Controller类接收的是一个抽象的接口变量Iback,则任何实现了该接口的对象都可以被Controller类对象所回调,Controller类的代码就再不用被修改,保证了代码对环境的适应性,无疑是一个很好的解决方案。

相关文章:

  • 儒家思想发展历程
  • C程序设计基础-数据类型
  • 【组成原理-指令】指令系统
  • 2022/08/31 day14:企业级解决方案
  • HJ26 字符串排序 ●●
  • Java程序员毕业N年系列----毕业二年
  • 抖音小程序模板全行业整理合集,抖音小程序制作平台分享
  • 嘉立创EDA专业版--彩色丝印?启用
  • 获评中国教育照明25强,利尔达引领教育照明行业“智变”
  • 武汉星起航:亚马逊卖家订单进入旺季迎猛涨,旺季如约而至
  • 刘亦菲生日当天,引发了我对正则的思考
  • Tomcat - 从源码阅读中分析核心组件
  • Android Glide应用中遇到问题
  • 个人云服务的搭建(折腾)之旅
  • 浅谈js中的深拷贝和浅拷贝
  • 2017年终总结、随想
  • chrome扩展demo1-小时钟
  • ES2017异步函数现已正式可用
  • es6
  • ES6 学习笔记(一)let,const和解构赋值
  • git 常用命令
  • JavaScript对象详解
  • java正则表式的使用
  • JS正则表达式精简教程(JavaScript RegExp 对象)
  • python 装饰器(一)
  • python_bomb----数据类型总结
  • React组件设计模式(一)
  • SOFAMosn配置模型
  • Vue.js-Day01
  • Vue.js源码(2):初探List Rendering
  • XForms - 更强大的Form
  • 从PHP迁移至Golang - 基础篇
  • 官方解决所有 npm 全局安装权限问题
  • 基于OpenResty的Lua Web框架lor0.0.2预览版发布
  • 扑朔迷离的属性和特性【彻底弄清】
  • 深入浏览器事件循环的本质
  • 使用Maven插件构建SpringBoot项目,生成Docker镜像push到DockerHub上
  • ​水经微图Web1.5.0版即将上线
  • ​总结MySQL 的一些知识点:MySQL 选择数据库​
  • (16)UiBot:智能化软件机器人(以头歌抓取课程数据为例)
  • (17)Hive ——MR任务的map与reduce个数由什么决定?
  • (第一天)包装对象、作用域、创建对象
  • (定时器/计数器)中断系统(详解与使用)
  • (附源码)spring boot智能服药提醒app 毕业设计 102151
  • (附源码)springboot建达集团公司平台 毕业设计 141538
  • (附源码)基于ssm的模具配件账单管理系统 毕业设计 081848
  • (附源码)计算机毕业设计SSM疫情下的学生出入管理系统
  • (力扣题库)跳跃游戏II(c++)
  • (切换多语言)vantUI+vue-i18n进行国际化配置及新增没有的语言包
  • (十三)Java springcloud B2B2C o2o多用户商城 springcloud架构 - SSO单点登录之OAuth2.0 根据token获取用户信息(4)...
  • (原創) 博客園正式支援VHDL語法著色功能 (SOC) (VHDL)
  • .NET Core/Framework 创建委托以大幅度提高反射调用的性能
  • .NET MVC之AOP
  • .NET:自动将请求参数绑定到ASPX、ASHX和MVC(菜鸟必看)
  • .NETCORE 开发登录接口MFA谷歌多因子身份验证