详解C#中通过委托来实现回调函数功能的方法
程序员文章站
2022-06-11 14:22:26
委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针。
回调函数
c++中的回调函数,就是用函数指针来实现的。类似的,c#中用委托,来实...
委托(delegate)是一种可以把引用存储为函数的类型,这类似于c++中的函数指针。
回调函数
c++中的回调函数,就是用函数指针来实现的。类似的,c#中用委托,来实现回调函数的功能。
回调函数为什么被称为回调函数?比如你调用了一个函数,那么就叫调用,但是如果你在调用一个函数的时候,还需要把一个函数提供给该函数,让这个函数来调用你的函数,那么你提供的这个函数就被称为回调函数(callback)。
对于python这样的动态语言而言,就没有c#,c++提供特殊的语法实现回调函数,因为在python中,函数也是一个对象,无论是当参数传,还是当函数的返回值,都不会有问题。
回调函数还被用来当作一个“插件”:
在c++的stl库中,排序函数的具体算法已经被实现,但是两个元素的具体比较办法,通过回调函数提供(比较函数),保证该算法可用于int,string等不同类型。
void sort( iterator start, iterator end ); void sort( iterator start, iterator end, strictweakordering cmp );
c#委托
委托常常被使用在事件处理中。因为可以将事件触发后的具体操作(该做哪些事情)委托给实现类。这个就是好莱坞法则,“don't call me, i will call you”。
这个例子来源于c#经典入门:
delegate double processdelegate(double param1, double param2); static double multiply(double param1, double param2) { return param1 * param2; } staitc double divide(double param1, double param2) { return param1 / param2; } if (input == "m") process = new processdelegate(multiply); else process = new processdelegate(divide);
但真实情况我们并不通过逻辑判断初始化回调函数,下面的这个函数插件的例子更常见。
static void executefunction(processdelegate process) { process(2.2, 3.3); }
c#委托实现回调的实例:
using system; using system.collections.generic; using system.componentmodel; using system.data; using system.drawing; using system.linq; using system.text; using system.windows.forms; using system.threading; namespace stockes { public partial class callback : form { public callback() { initializecomponent(); //初始化回调方法 writeboxcallback1 = new writeboxcallback1(write1); writeboxcallback2 = new writeboxcallback2(write2); } //声明委托已实现回调机制 private delegate void writetextbox(char ch); private writetextbox writetextbox; //text1的回调 private delegate void writeboxcallback1(char ch); private writeboxcallback1 writeboxcallback1; //text2的回调 private delegate void writeboxcallback2(char ch); private writeboxcallback2 writeboxcallback2; private void button1_click(object sender, eventargs e) { if (checkbox1.checked) { groupbox4.text = "正在运行。。。"; groupbox4.refresh(); textbox1.clear(); textbox1.refresh(); thread th1 = new thread(new threadstart(dowrite1));//创建线程1 th1.start();//启动线程1 } if (checkbox2.checked) { groupbox2.refresh(); groupbox5.text = "正在运行。。。"; groupbox5.refresh(); textbox2.clear(); textbox2.refresh(); thread th2 = new thread(new threadstart(dowrite2));//创建线程2 th2.start();//启动线程2 } } //text1使用回调语句 private void calltex1(char ch) { textbox1.invoke(writeboxcallback1,ch); } //text2使用回调语句 private void calltext2(char ch) { textbox2.invoke(writeboxcallback2,ch); } //使用委托 private void writetex(writetextbox write) { string str = textbox3.text.trim(); for (int i = 0; i < str.length; i++) { write(str[i]); datetime now = datetime.now; while (now.addseconds(1) > datetime.now) { } } } //text1添加值 private void write1(char ch) { textbox1.appendtext(ch+"\r"); } //text2添加值 private void write2(char ch) { textbox2.appendtext(ch+"\r"); } //线程1调用的方法 private void dowrite1() { if (checkbox1.checked) { writetextbox = new writetextbox(calltex1); writetex(writetextbox); } } //线程2调用的方法 private void dowrite2() { if (checkbox2.checked) { writetextbox = new writetextbox(calltext2); writetex(writetextbox); } } } }
上一篇: C#使用SignalR实现进度条
下一篇: VS中常用C#代码段快速输入总结