C#回调函数的简单讲解与应用例子
using System;
namespace CallBackTest
{
class Program //用户层,执行输入等操作
{
static void Main(string[] args)
{
CalculateClass cc = new CalculateClass();
FunctionClass fc = new FunctionClass();
int result1 = cc.PrintAndCalculate(2, 3, fc.GetSum);
Console.WriteLine("调用了开发人员的加法函数,处理后返回结果:" + result1);
int result2 = cc.PrintAndCalculate(2, 3, fc.GetMulti);
Console.WriteLine("调用了开发人员的乘法函数,处理后返回结果:" + result2);
Console.ReadKey();
}
}
class FunctionClass //开发层处理,开发人员编写具体的计算方法
{
public int GetSum(int a, int b)
{
return (a + b);
}
public int GetMulti(int a, int b)
{
return (a * b);
}
}
#region 实际开发中,下面这个类会封装起来,只提供函数接口。相当于系统底层
class CalculateClass
{
public delegate int SomeCalculateWay(int num1, int num2);
//将传入参数在系统底层进行某种处理,具体计算方法由开发者开发,函数仅提供执行计算方法后的返回值
public int PrintAndCalculate(int num1 , int num2 , SomeCalculateWay cal)
{
Console.WriteLine("系统底层处理:" + num1);
Console.WriteLine("系统底层处理:" + num2);
return cal(num1, num2);//调用传入函数的一个引用
}
//可以封装更多的业务逻辑方法
}
#endregion
}
直接复制进控制台项目即可运行。
运行结果:
感觉例子还是比较直白的。例子能看懂就不用看下面的了。
下面详细解释一下(包含一些关于封装的意义):
1、中间的FunctionClass中的GetSum()和GetMulti()两个函数称为回调函数。可以看到整个程序中并没有哪个地方通过类似GetSum(1,2)这种形式调用了该函数,只有将其当作另一个函数的参数来进行调用。如cc.PrintAndCalculate(2,
3, fc.GetSum)。
下面是百度百科的定义:
回调函数不是由该函数的实现方直接调用,而是在特定的事件或条件发生时由另外的一方调用的,用于对该事件或条件进行响应。
有的同学可能会问了,那为什么不直接写int result1 = GetSum(1,2)呢?岂不是更方便?这就涉及到封装和实际开发的问题了 ↓
_________________________________
我们假想一下这个情况:
我们的项目是个核武器控制器,假设并没有涉及到回调函数。当用户输入1,2并且执行GetSum(1,2)的时候,这个工程会把1,2写进核武器的发射系数里,比如方向方位等,然后GetSum求得发射距离,之后进行发射。
看起来也很完美?没什么瑕疵?
不,有没有想过万一哪天操作失误了呢。万一哪天某个人输入错了,把-1,-2输入进去了,现在倒好,本来要打到外面去的导弹打到自己家了,这个损失就是不可估量的了。
你可能又会说了,那让程序员在客户端(用户端)判断一下呗,比如加一句 if(a>0 && b>0) getsum(a,b);
那你有没想过,万一哪天这个程序员的代码写错了一行呢?或者派了一个像我一样很菜的实习生过来写代码?岂不是又要把导弹打到自己家了吗hhhhhhhh。所以,在实际大型应用中,“把参数写进核武器” 这个操作的代码并不是所有人都能接触到的,只有项目里最核心的工程师经过反复测验才能应用上去的,而且要对这些参数甚至是结果进行必要的判断,并且如果要修改代码也是会经过慎重考量的,因为你一改,相当于整个项目底层都进行了改变,所有调用你函数的人执行效果也都会发生改变。
以上就是封装的意义。(当然封装还有其他意义这里就不赘述了)
______________________________________________________________________
2、在实际开发中,CalculateClass这个类会被封装起来,比如提供一个dll文件给你,你通过引用dll来调用里面的参数或者函数。一般项目里的大佬/主程都会把这些底层的东西打包进dll,防止误操作使得系统崩溃,也让外界不能轻易访问底层的东西。
在这个类中,public delegate int SomeCalculateWay(int num1, int num2); 这一语句声明了一个委托,后面定义的SomeCalculateWay cal就代表着cal是一个带有两个int参数的函数。关于委托的例子和应用这里也不多讲了,能理解就好。
3、在用户层的main函数里,用户可以通过输入参数2,3,然后获取一个开发人员的方法比如getsum,然后把这些作为参数,调用底层的函数,再得到想要的效果。这样子不管是用户还是开发人员误操作了,最后都会被底层的函数给判断出来,从而不会执行错误的结果而造成损失。
---------------------
作者:董董在这
来源:CSDN
原文:https://blog.csdn.net/sajiazaici/article/details/78702144
版权声明:本文为博主原创文章,转载请附上博文链接!
C#回调函数的简单讲解与应用例子的更多相关文章
- C#回调函数的简单讲解与应用例子(最简单讲解,大神绕道)
本博客一直以来的宗旨就是:用最简单的方式讲清楚不复杂的问题. 因为本人也很菜所以也没法讲太复杂HHHHHH...... 所以如果哪天某个大神看到了觉得讲的有问题欢迎指出. 话不多说进入正题.. ——— ...
- C++ 回调函数的简单例子(转)
原文转自 http://blog.csdn.net/wnlwcg/article/details/6930990# 1.调用端 // 下面的这个_stdcall很重要的 void _stdcall T ...
- 在Java中如何编写回调函数,以及回调函数的简单应用
import static java.lang.System.out; import static java.lang.System.err; import java.util.logging.Lev ...
- JavaScript 回调函数的简单示例
回调函数 回调函数也被称为高阶函数 所谓高阶函数,就是说值 函数作为参数被传递或者返回值输出 操作函数的函数称为 高阶函数 把一段可执行的代码(一个函数)作为参数传递给其他的代码(另一个函数),并在需 ...
- 进程池与回调函数与正则表达式和re爬虫例子
# 使用进程池的进程爬取网页内容,使用回调函数处理数据,用到了正则表达式和re模块 import re from urllib.request import urlopen from multipro ...
- JS中回调函数的简单用法
a能拿b,b能拿到c,c能拿到d,实现a拿到d的东西. function a() { b(function (data) { console.log(data); }); } function b(c ...
- 理解javascript中的回调函数(callback)【转】
在JavaScrip中,function是内置的类对象,也就是说它是一种类型的对象,可以和其它String.Array.Number.Object类的对象一样用于内置对象的管理.因为function实 ...
- 理解和使用 JavaScript 中的回调函数
理解和使用 JavaScript 中的回调函数 标签: 回调函数指针js 2014-11-25 01:20 11506人阅读 评论(4) 收藏 举报 分类: JavaScript(4) 目录( ...
- [转]理解与使用Javascript中的回调函数
在Javascript中,函数是第一类对象,这意味着函数可以像对象一样按照第一类管理被使用.既然函数实际上是对象:它们能被“存储”在变量中,能作为函数参数被传递,能在函数中被创建,能从函数中返回. 因 ...
随机推荐
- java自动生成表单简单实例
数据库表设置 tb_form(form表单) 字段 类型 约束 说明 Id Int 主键 主键 Formid Varchar2(20) 唯一 Form表单id的值 Action Varchar2(20 ...
- php设计模式课程---1、什么是设计模式
php设计模式课程---1.什么是设计模式 一.总结 一句话总结:经典场景的经典解决方法. 经典场景的经典解决方法 1.设计模式使用的通俗场景有哪些? 比如:拍电影时,常用设计模式 感情狗血剧:误会模 ...
- unity3D实现多点触碰
实现多点触碰是利用input这个类里面的方法实现的. 从edit-project settings-input就可以看到input能够得到的轴. 想要读取轴向可以使用Input.GetAxis方法获取 ...
- 分享知识-快乐自己:Nginx概述及如何使用
概述: 什么是 Nginx? Nginx (engine x) 是一款轻量级的 Web 服务器 .反向代理服务器及电子邮件(IMAP/POP3)代理服务器. 什么是反向代理? 反向代理(Reverse ...
- Vue2.0总结———vue使用过程常见的一些问题
Vue目前的的开发模式主要有两种:1.直接页面级的开发,script直接引入Vue2.工程性开发,webpack+loader或者直接使用脚手架工具Vue-cli,里面的文件都配置好了 webpack ...
- BEC listen and translation exercise 35
高中听力: At five o'clock, we have afternoon tea, but we don't have it in the kitchen. Father's Day is t ...
- OPcache
1.介绍 OPcache 通过将 PHP 脚本预编译的字节码存储到共享内存中来提升 PHP 的性能, 存储预编译字节码的好处就是 省去了每次加载和解析 PHP 脚本的开销 2.配置 2.1 opcac ...
- linux命令学习笔记(21):find命令之xargs
xargs是一条Unix和类Unix操作系统的常用命令.它的作用是将参数列表转换成小块分段传递给其他命令,以避免参数列表过长的问题 xargs的作用一般等同于大多数Unix shell中的反引号,但更 ...
- 【leetcode刷题笔记】Path Sum
Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up all ...
- FFmpeg 的sws_getContext函数 、sws_scale函数
FFmpeg里面的sws_scale库可以在一个函数里面同时实现:1.图像色彩空间转换:2.分辨率缩放:3.前后图像滤波处理. 其核心函数主要有三个: // 初始化sws_scalestruct Sw ...