zoukankan      html  css  js  c++  java
  • 委托编程指南

     一.什么是委托

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

    二.为什么使用委托

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

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

    主窗体:

    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

  • 相关阅读:
    ArcGIS Engine渲染
    C# char 和string之间转换
    C#播放声音的四种方法 +AxWindowsMediaPlayer的详细用法
    Navicat Premium 12安装及永久破解方法,亲测有效~
    使用WebDriver采样器将JMeter与Selenium集成
    jmeter响应结果中文乱码解决
    jmeter元件执行顺序
    jmeter使用函数助手实现参数化
    jmeter使用csv进行参数化
    jmeter利用http代理服务器录制脚本
  • 原文地址:https://www.cnblogs.com/Artist007/p/11043395.html
Copyright © 2011-2022 走看看