在编程中,委托有利于解耦,同时也是异步编程的基础,但是由于书写的方式跟平常不太一样,所以委托就跟反射一样,比较难于接受。

委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值,委托是一种引用方法的类型。一旦为委托分配了方法,委托将与该方法具有完全相同的行为。委托方法的使用可以像其他任何方法一样,具有参数和返回值。

与委托的签名(由返回类型和参数组成)匹配的任何方法都可以分配给该委托。这样就可以通过编程方式来更改方法调用,还可以向现有类中插入新代码。只要知道委托的签名,便可以分配自己的委托方法。

将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。例如,可以向排序算法传递对比较两个对象的方法的引用。分离比较代码使得可以采用更通用的方式编写算法。

委托具有以下特点:

  • 委托类似于 C++ 函数指针,但它是类型安全的。

  • 委托允许将方法作为参数进行传递。

  • 委托可用于定义回调方法。

  • 委托可以链接在一起;例如,可以对一个事件调用多个方法。

  • 方法不需要与委托签名精确匹配。有关更多信息,请参见协变和逆变。

  • C# 2.0 版引入了匿名方法的概念,此类方法允许将代码块作为参数传递,以代替单独定义的方法。



以下,为委托与异步委托的实例代码:

using System;
using System.Collections.Generic;
using System.Text;

namespace TestWindowsApplication
{
    
public class Maths
    
{
        
public int add(int x, int y)
        
{
            
return x + y;
        }


        
public int minus(int x, int y)
        
{
            
return x - y;
        }

    }

}


  1using System;
  2using System.Collections.Generic;
  3using System.ComponentModel;
  4using System.Data;
  5using System.Drawing;
  6using System.Text;
  7using System.Windows.Forms;
  8
  9namespace TestWindowsApplication
 10{
 11    public partial class Form1 : Form
 12    {
 13        //定义一个委托
 14        public delegate int MyHandler(int x, int y);
 15
 16        public Form1()
 17        {
 18            InitializeComponent();
 19        }

 20
 21        private void Form1_Load(object sender, EventArgs e)
 22        {
 23
 24        }

 25
 26        private void button1_Click(object sender, EventArgs e)
 27        {
 28            int x = this.textBox1.Text == "" ? 0 : int.Parse(this.textBox1.Text);
 29            int y = this.textBox2.Text == "" ? 0 : int.Parse(this.textBox2.Text);
 30
 31            Maths maths = new Maths();
 32            //绑定到maths实例的add方法
 33            MyHandler addhandler = new MyHandler(maths.add);
 34            //调用
 35            int addResult = addhandler(x, y);
 36            MessageBox.Show(string.Format("{0} values: {1}", addhandler.Method.Name, addResult));
 37        }

 38
 39        private void button2_Click(object sender, EventArgs e)
 40        {
 41            int x = this.textBox1.Text == "" ? 0 : int.Parse(this.textBox1.Text);
 42            int y = this.textBox2.Text == "" ? 0 : int.Parse(this.textBox2.Text);
 43
 44            StringBuilder sb = new StringBuilder();
 45            Maths maths = new Maths();
 46
 47            MyHandler all = null;
 48            //绑定到maths实例的add方法
 49            MyHandler add = new MyHandler(maths.add);
 50            //绑定到maths实例的minus方法
 51            MyHandler minus = new MyHandler(maths.minus);
 52
 53            //链接
 54            all += add;
 55            all += minus;
 56
 57            //定义传入参数
 58            object[] param ={ x, y };
 59
 60            //获取目标委托数组
 61            Delegate[] delegates = all.GetInvocationList();
 62            foreach (Delegate dg in delegates)
 63            {
 64                try
 65                {
 66                    //动态调用当前委托所表示的方法
 67                    int addResult = (int)dg.DynamicInvoke(param);
 68                    sb.AppendFormat("{0} values: {1}\n", dg.Method.Name, addResult);
 69                }

 70                catch (Exception et)
 71                {
 72                    MessageBox.Show(et.Message);
 73                }

 74            }

 75
 76            MessageBox.Show(sb.ToString());
 77        }

 78
 79        private void button3_Click(object sender, EventArgs e)
 80        {
 81            int x = this.textBox1.Text == "" ? 0 : int.Parse(this.textBox1.Text);
 82            int y = this.textBox2.Text == "" ? 0 : int.Parse(this.textBox2.Text);
 83
 84            Maths maths = new Maths();
 85            //绑定到maths实例的add方法
 86            MyHandler addhandler = new MyHandler(maths.add);
 87
 88            //异步调用开始
 89            IAsyncResult ar = addhandler.BeginInvoke(x, y, nullnull);
 90
 91            //异步操作是否完成
 92            while (!ar.IsCompleted)
 93            {
 94                //如果没完成,当前线程阻止时间为10毫秒
 95                System.Threading.Thread.Sleep(10);
 96            }

 97            //异步调用完成,返回结果
 98            int addResult = addhandler.EndInvoke(ar);
 99
100            MessageBox.Show(string.Format("{0} values: {1}", addhandler.Method.Name, addResult));
101        }

102
103    }

104}
posted on 2006-11-23 02:18  Project E  阅读(635)  评论(0编辑  收藏  举报