博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
C# 委托和事件
阅读量:6388 次
发布时间:2019-06-23

本文共 3394 字,大约阅读时间需要 11 分钟。

一、是什么

1)委托包含对方法而不是方法名称的引用。使用委托可以在运行时动态设定要调用的方法,不知道方法名称,也可以调用方法,执行(或调用)一个委托将执行该委托引用的方法。

2)委托将名称与方法的定义连接起来,即将方法的实现附加到该名称。这样便可以使用该名称调用特定的方法。但是,委托要求方法的实现和委托必须具有相同的方法签名(也就是说,他们应该具有相同数量/类型的参数),并有相同类型的返回值。

3)委托更像一个具有通用的方法名称,在不同的情况将该名称指向不同的方法,并通过委托执行这些方法。

二、怎么用

使用委托包括三个步骤:

1)定义委托

2)实例化委托

3)使用委托

我们上一个例子:

class Program  {      //定义一个委托      public delegate int Call(int num1, int num2);        class Math      {          public int Mutiply(int num1, int num2)          {              return num1 * num2;          }            public int Divide(int num1, int num2)          {              return num1 / num2;          }      }        static void Main(string[] args)      {          Call objCall;          Math objMath = new Math();          objCall = new Call(objMath.Mutiply);//实例化一个委托                  int result = objCall(5, 3);//使用委托          Console.WriteLine("结果为 {0}", result);      }  }

值得说明是,

objCall = new Call(objMath.Mutiply);//实例化一个委托  

objCall = objMath.Mutiply; //直接给委托赋值

这两种方式效果是一样的,只是两种不同的写法。用.net reflector反编译上述代码,会发现其实objCall = objMath.Mutiply最终还是会编译生成objCall = new Call(objMath.Mutiply)。

 上面的例子,我们再进一步,用匿名委托实现:

static void Main(string[] args)  {      Call objCall = delegate(int num1, int num2) { return num1 * num2; };//匿名委托      int result = objCall.Invoke(3, 5);//使用委托      Console.WriteLine("结果为 {0}", result);//输出:结果为 15  }

我们还可以将:

int result = objCall.Invoke(3, 5);//使用委托

替换为:

int result = objCall(3, 5);//使用委托

效果是一样的。

 再进一步,用Lambda表达式进行简化,可以将:

Call objCall = delegate(int num1, int num2) { return num1 * num2; };//匿名委托

替换为:

Call objCall = (int num1, int num2) => { return num1 * num2; };//Lambda表达式

更简化一步,变为:

Call objCall = (num1, num2) => { return num1 * num2; };//Lambda表达式

这就是C#委托的进化过程以及C#Lambda表达式对委托的支持。

 三、什么时候用

1)委托类似于C语言中的函数指针,可以将方法作为函数的参数进行传递

2)当不知道方法的具体实现时,就可以定义个委托,让它替我们干活

3)我们在编程时用的最多的就是事件注册时使用。

比如:

this.button1.Click += new EventHandler(button1_Click);//button1注册Click事件
private void button1_Click(object sender, EventArgs e)  {      //方法具体实现内容  }

可以看到方法button1_Click作为参数传递给了EventHandler委托。

再比如在线程方法中:

Thread th = new Thread(new ThreadStart(Method));//这里的ThreadStart就是一个委托,里面可以直接传一个方法名Method,以委托的形式调用方法  th.IsBackground = true;  th.Start();

 四、典型应用

比如两个窗体Form1(一个文本框,一个按钮)、Form2(一个文本框,一个按钮)之间进行传值,Form1到Form2可以通过构造函数传值,但如果要将Form2的值传回给Form1该怎么办呢?这里就可以用到委托,这也是委托的经典应用场景之一。

 Form1.cs部分代码:

private void button1_Click(object sender, EventArgs e) {     Form2 form2 = new Form2();     //通过public变量传值     form2.text = this.textBox1.Text;     //通过委托将子窗体的值传回主窗体     form2.delegateShow = form2_ShowDelegateEventHandler;     //通过注册事件将子窗体的值传回主窗体     form2.ShowDelegateEventHandler += new Form2.ShowDelegate(form2_ShowDelegateEventHandler);     form2.Show(); } void form2_ShowDelegateEventHandler(string text) {     this.textBox1.Text = text; }

 Form2.cs部分代码:

public delegate void ShowDelegate(string text);//声明委托public event ShowDelegate ShowDelegateEventHandler;//声明事件public string text;//public变量public ShowDelegate delegateShow;//public委托变量private void Form2_Load(object sender, EventArgs e){    this.textBox1.Text = text;}private void button1_Click(object sender, EventArgs e){    //写法1:用事件    if (ShowDelegateEventHandler != null)        ShowDelegateEventHandler(this.textBox1.Text);    //写法2:用委托    delegateShow(this.textBox1.Text);    this.Close();}

 五、总结

1)委托是方法的签名,可以将委托作为方法的参数进行传递

2)事件基于委托,或者说事件是特殊的委托

3)委托可以用匿名委托简化代码(不需要再声明委托,然后实现),还可以用Lambda表达式进一步简化匿名委托(这也是C#推荐的方式)。

 

代码下载:

转载地址:http://drbha.baihongyu.com/

你可能感兴趣的文章
Oracle命令
查看>>
转载-没有IE就没有伤害!浏览器兼容性问题解决方案汇总
查看>>
常用 tcpdump 抓包方式
查看>>
Geek's Collection(幂运算)
查看>>
easy bootstrap模板
查看>>
Hdu 4734-F(x) 数位dp
查看>>
DRUID连接池的实用 配置详解
查看>>
html&css精华总结
查看>>
ImportError: No module named tornado.ioloop 记录过程
查看>>
[转] SSH 密钥认证机制
查看>>
hihocoder [Offer收割]编程练习赛14 小Hi和小Ho的礼物
查看>>
JQuery EasyUI 动态改变表单项的验证守则
查看>>
Jmeter如何操作数据库
查看>>
iOS开发设置View某个角为圆角
查看>>
【python】python path,macports,easy-install,numpy,scipy,ipython,matplotlib,集成工具...
查看>>
学习进度总结
查看>>
ACCESS模糊查询出现"内存溢出"原因是日文片假名
查看>>
Error setting expression 'XXX' with value 设置表达式“XXX”时出错 解决方法
查看>>
javascript获取url参数和script标签中获取url参数
查看>>
CF359D:Pair of Numbers(数论)
查看>>