委托编程指南

 一.什么是委托

 委托的本质是一种数据类型,和类类型一样,只是一种数据类型没什么神秘的地方,委托是一种引用数据类型,表示对具有特定参数列表和返回类型的方法的引用。在实例化委托时,你可以将其实例与任何兼容的方法(参数和返回值,简称方法的签名)相关联,再通俗一点的讲,委托是可以将"方法"定义成变量的数据类型

二.为什么使用委托

 委托用于将方法作为参数传递给其他方法,当某个方法直接调用有困难时,我们就想找一个"中间人"来帮我们调用,这个中间人就是委托。

 委托的简单应用的第一个例子:从窗体向主窗体传递值,实现主窗体窗体刷新

主窗体:

public partial class FrmMain : Form
    {
        public FrmMain()
        {
            InitializeComponent();

            FrmOther objFrm = new FrmOther();

            //将从窗体的委托变量和主窗体的对应方法关联
            objFrm.msgSender = this.Receiver;

            objFrm.Show();
        }


        /// <summary>
        /// 接收委托传递的信息
        /// </summary>
        /// <param name="counter"></param>
        private void Receiver(string counter)
        {
            this.lblCount.Text = counter;
        }
    }

    //【1】声明委托
    public delegate void ShowCounter(string counter);

从窗体:

   public partial class FrmOther : Form
    {
        public FrmOther()
        {
            InitializeComponent();
        }
        //根据委托创建委托对象
        public ShowCounter msgSender;

        //计数
        private int counter = 0;
        private void btnClick_Click(object sender, EventArgs e)
        {
            counter++;
            if (msgSender != null)
            {
                msgSender(counter.ToString());
            }
        }
    }

委托的简单应用第二个例子 主窗体向从窗体广播:

主窗体代码:

 public FrmMain()
        {
            InitializeComponent();

            FrmOther01 objFrm01 = new FrmOther01();
            FrmOther02 objFrm02 = new FrmOther02();
            FrmOther03 objFrm03 = new FrmOther03();

            //将委托变量和具体方法关联
            this.msgSender += objFrm01.Receiver;
            this.msgSender += objFrm02.Receiver;
            this.msgSender += objFrm03.Receiver;

            objFrm01.Show();
            objFrm02.Show();
            objFrm03.Show();

        }

        //根据委托创建委托对象
        public ShowCounter msgSender;

        private int counter = 0;

        private void btnClick_Click(object sender, EventArgs e)
        {
            counter++;
            //同时对三个从窗体发消息
            this.msgSender.Invoke(counter.ToString());

            
        }

        private void btnReset_Click(object sender, EventArgs e)
        {
            counter = 0;
            this.msgSender("0");
        }
    }

    //【1】声明委托
    public delegate void ShowCounter(string counter);

从窗体代码:

 public partial class FrmOther01 : Form
    {
        public FrmOther01()
        {
            InitializeComponent();
        }

        /// <summary>
        /// 接收委托传递的信息
        /// </summary>
        /// <param name="counter"></param>
        public void Receiver(string counter)
        {
            this.lblCount.Text = counter;
        }
    }

 

三.动态创建委托

委托是C#实现事件的基础,有时候不可避免的要动态创建委托,实际上委托也是一种类型:System.Delegate,所有的委托都是从这个类派生而来,System.Delegate提供了一些方法可以动态创建委托:

     

                                                           

A.创建静态方法的委托

CreateDelegate(Type, MethodInfo) 和 CreateDelegate(Type, MethodInfo, Boolean) 的功能是相同的,都是可以创建静态方法的委托,或者是显式提供实例方法的第一个隐藏参数(称开放的实例方法,从 .Net Framework 2.0 以后支持)的委托。举个例子:

 public partial class Form1 : Form
    {
        public delegate void D1(string s);
        Type objType = Type.GetType("WindowsFormsApplication4.TestClass");

        D1 d1;
        public Form1()
        {
            InitializeComponent();
            Delegate objDelegate = CreateStaticDelegate();
            d1 = (D1)objDelegate;
            d1("11111111");
        }

        Delegate CreateStaticDelegate()
        {
            Delegate objDelegate = Delegate.CreateDelegate(typeof(D1), objType.GetMethod("TestStaticMethod"));
            return objDelegate;
        }
    }

    public class TestClass
    {
        public static void TestStaticMethod(string str) { }
        public void TestMethod() { }
    }

 

创建静态方法TestStaticMethod的委托 需要typeof(Action<string>) ,已及需要用反射获取需要被触发的方法。

B.创建实例方法委托

要创建实例方法 TestMethod 方法的委托,例子如下:

 1   public partial class Form1 : Form
 2     {
 3         public delegate void D1(string s);
 4         Type objType = Type.GetType("WindowsFormsApplication4.TestClass");
 5         //TestClass objTestClass = new TestClass();
 6         D1 d1;
 7 
 8         public Form1()
 9         {
10             InitializeComponent();
11             Delegate objDelegate = CreateDelegate();
12             d1 = (D1)objDelegate;
13             d1("11111111");
14         }
15         Delegate CreateDelegate()
16         {
17 
18             object objTestClass = Activator.CreateInstance(objType);
19 
20 
21             Delegate objDelegate = Delegate.CreateDelegate(typeof(D1), objTestClass, "TestMethod");
22             return objDelegate;
23         }
24     }
25 
26     public class TestClass
27     {
28         public static void TestStaticMethod(string str) { }
29         public void TestMethod(string str) 
30         {
31             Console.WriteLine(str);
32 
33             Console.Read();
34         
35         }
36     }

关于Delegate其它的重载方法可以参照MSDN,链接如下:

https://docs.microsoft.com/en-us/dotnet/api/system.delegate.createdelegate?view=netframework-4.5

 

posted @ 2019-06-18 14:40  大艺术家007  阅读(327)  评论(1编辑  收藏  举报