欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

详解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); 
      } 
    } 
  } 
}