zoukankan      html  css  js  c++  java
  • 委托

            委托是C#1.0提出的一种功能,如今C#都将更新到C#10.0了(最新8.0),对委托的用法还只是停留在原地,略等于不知道。今天自己来学习,解锁下“委托”这个技能,本文综合圈子各位大佬的文章总结而来,若有错误或不足,欢迎斧正。

            委托在.net framwork中的应用非常广泛(CS项目中经常用到,BS项目相对要少点);本文将讲述委托的概念(什么是委托 What)、委托的作用(为什么要使用委托 Why)、委托怎么用(How);

    委托的概念-WHAT:

           委托:把事情托付给别人或别的机构(办理)(百度百科释义:https://baike.baidu.com/item/%E5%A7%94%E6%89%98/34711?fr=aladdin);直观点就是,本该自己做的事情,交给别人做;

           C#中的委托:委托实际为一种 中间人 ,A需要C去做某件事情 而由B去调用C来做事。委托是用户自定义的类,它定义了方法的类型。储存的是一系列具有相同参数和返回类型方法的地址列表,调用委托时,此委托列表的所有方法都将被执行。总的来说:委托是方法的抽象,它代表了一组方法的共同特征。

    委托的作用-WHY:

          用来实现传递回调函数;将方法引用封装在委托对象内。然后可以将该委托对象传递给可调用所引用方法的代码,而不必在编译时知道将调用哪个方法。

    委托的用法-HOW:

         1:先声明定义一个委托

         2:实例化一个委托,实例化的时候需要绑定方法(绑定的方法必须与定义的委托具有相同参数列表和返回值,否则编辑器会报错)

         3:调用委托    

    • 定义委托的关键词:delegate
    • 委托是一种类型,它可以声明在类的外部,也可以在类的内部声明;
    using System;
    using System.Collections.Generic;
    using System.Text;
    
    namespace Tools
    {
        public delegate void MyDelegateOutClass();//类外部申请一个委托
        public class LearnDelegate
        {
            public delegate void MyDelegateInClass();//类内部申请一个委托
        }
    }
    • 示例一:无参数、无返回值委托和方法绑定
        public class LearnDelegate
        {
            //1:声明一个无参数无返回值的委托
            public delegate void MyDelegateNoParmNoreturn();public static void Run()
            {
                //1:无参数无返回值的委托实例化与调用
                MyDelegateNoParmNoreturn method1 = new MyDelegateNoParmNoreturn(NoParmsNoReturns);
                method1.Invoke();
            }
            public static void NoParmsNoReturns()
            {
                Console.WriteLine("这是一个无参数、无返回值的方法");
            }
        }

      从示例一可以看出:委托的实例化和类的实例化相似:在使用委托的时候,你可以像对待一个类一样对待它。即1:先声明:2:再实例化。只是有点不同,类在实例化之后叫对象或实例,但委托在实例化后仍叫委托;委托的实例化需要绑定方法,也就是委托要办的事情

    • 示例二:有参数无返回值委托和方法绑定
        public class LearnDelegate
        {
            //1:声明一个无参数无返回值的委托
            public delegate void MyDelegateNoParmNoreturn();
    
            //2:声明一个有参数无返回值的委托
            public delegate void MyDelegateHasParmsNoReturn(string name, string sex);
    public static void Run()
            {
                //1:无参数无返回值的委托实例化与调用
                MyDelegateNoParmNoreturn method1 = new MyDelegateNoParmNoreturn(NoParmsNoReturns);
                method1.Invoke();
    
                //2:有参数无返回值的委托实例化与调用
                MyDelegateHasParmsNoReturn method2 = new MyDelegateHasParmsNoReturn(HasParmsNoReturns);
                method2("zhangsan", "");
            }
            public static void NoParmsNoReturns()
            {
                Console.WriteLine("这是一个无参数、无返回值的方法");
            }
    
            public static void HasParmsNoReturns(string _name)
            {
                Console.WriteLine("这是一个有参数、无返回值的方法");
            }
        }
    • 示例三:有参数、有返回值的委托和方法绑定
    public class LearnDelegate
        {
            //1:声明一个无参数无返回值的委托
            public delegate void MyDelegateNoParmNoreturn();
    
            //2:声明一个有参数无返回值的委托
            public delegate void MyDelegateHasParmsNoReturn(string name, string sex);
    
            //3声明一个有参数有返回值的委托
            public delegate string MyDelegateHasParmsHasReturn(string name);
            public static void Run()
            {
                //1:无参数无返回值的委托实例化与调用
                MyDelegateNoParmNoreturn method1 = new MyDelegateNoParmNoreturn(NoParmsNoReturns);
                method1.Invoke();
    
                //2:有参数无返回值的委托实例化与调用
                MyDelegateHasParmsNoReturn method2 = new MyDelegateHasParmsNoReturn(HasParmsNoReturns);
                method2("zhangsan", "");
    
                //3:有参数有返回值的委托实例化与调用
                MyDelegateHasParmsHasReturn method3 = new MyDelegateHasParmsHasReturn(HasParmsHasReturns);
                var name = method3("lisi");
            }
            public static void NoParmsNoReturns()
            {
                Console.WriteLine("这是一个无参数、无返回值的方法");
            }
    
            public static void HasParmsNoReturns(string _name)
            {
                Console.WriteLine("这是一个有参数、无返回值的方法");
            }
            public static string HasParmsHasReturns(string _name)
            {
                Console.WriteLine("这是一个有参数、有返回值的方法");
                return "";
            }
    
            public static void HasParmsNoReturns(string _name, string _sex)
            {
                Console.WriteLine("这是一个有两个参数、无返回值的方法");
            }
    
    
        }
    • 自带委托Action
      • Action为C#自带的委托类型,无需另外声明委托,可直接创建一个委托实例
      • Action为无返回值的委托类型
     public static void HasParmsNoReturns(string _name, string _sex)
            {
                Console.WriteLine("这是一个有两个参数、无返回值的方法");
            }
    
            public static void ShowAction()
            {
                Action action = new Action(NoParmsNoReturns);
                action(); //委托实例调用 => action.Invoke();
    
                Action<string,string> action2 = new Action<string,string>(HasParmsNoReturns);
                action2("","");//有参数 无返回值,此时参数类型必须标明在声明委托中
            }
    • 自带委托 Func
      • Func 为C#自带的委托类型,无需另外声明委托,可直接创建一个委托实例
      • Func 为有返回值的委托类型
     public static string HasParmHasReturn(string name,string address,string email)
            {
                return "hello world";
            }
    
            public static void ShowFunc()
            {
                Func<string> fun1 = new Func<string>(NoParmHasReturn);
                fun1();//无参数,有返回值
    
    
                Func<string, string, string,string> fun2 = new Func<string, string, string,string>(HasParmHasReturn);
                fun2("","",""); //有参数,有返回值
            }

    注意:当Func中只有一个参数,说明需要绑定的是无参数的有返回值的方法,Func的唯一参数为返回值类型;

              Func中的参数类型、返回值类型都需要标明,在泛型类声明中,当有返回值得时候,最后一个参数类型为返回值类型

    参数我们试下将方法的返回值类型改为int,编译报错;

     正确写法:

            public static int HasParmHasReturn(string name,string address,string email)
            {
                return 123;
            }
    
            public static void ShowFunc()
            {
                Func<string> fun1 = new Func<string>(NoParmHasReturn);
                fun1();
    
    
                Func<string, string, string,int> fun2 = new Func<string, string, string,int>(HasParmHasReturn);
                fun2("","",""); 
            }
    • 多播委托
      • 只需要调用一个委托,就可以一次执行这个委托中包含的所有方法(一个委托能够指向多个函数方法)
      • 多播委托引用的函数的返回类型必须是void,否则,我们只能得到最后一个函数调用结果。

    使用示例:

            /// <summary>
            /// 多播委托使用示例
            /// </summary>
            public static void ShowMore()
            {
                Action action = Show1;
                action += Show2;
                action += Show3;
                action += Show4;
                action -= Show3;
                action += Show3;
    
                action();
    
                Console.ReadLine();
            }
            public static void Show1()
            {
                Console.WriteLine("show T1");
            }
            public static void Show2()
            {
                Console.WriteLine("show T2");
            }
            public static void Show3()
            {
                Console.WriteLine("show T3");
            }
            public static void Show4()
            {
                Console.WriteLine("show T4");
            }

    看到示例,可能会有点懵;我们先看下运行结果,在作分析:

     其中有

    1. 委托名=方法名 :实例化委托赋值语法的简写
    2. “+=方法名”  :委托绑定方法,将相同参数列表的函数绑定到统一委托中执行
    3. “-=方法名”  :取消委托绑定的方法,将方法从委托方法列表中移除

    这个是委托实例化的简写  即

    MyDelegateNoParmNoreturn method1 = new MyDelegateNoParmNoreturn(NoParmsNoReturns);
     //等效于
    MyDelegateNoParmNoreturn method1 = NoParmsNoReturns;

    注:第一次用的“=”,是赋值的语法;第二次,用的是“+=”,是绑定的语法。如果第一次就使用“+=”,将出现“使用了未赋值的局部变量”的编译错误。

    然后我们来看多播委托的执行过程:

    首先我们用了C#自带的无返回值的Action,赋值了一个Show1的方法;然后为该委托绑定了Show2、Show3、Show4的方法;再然后取消了Show3的绑定,最后又重新绑定了Show3;所以该委托依次执行结果为:show T1 、show T2、show T3(后被移除不输出)、showT4、showT3(重新绑定ShowT3,最后输出)

    总结:使用委托可以将多个方法绑定到同一个委托变量,当调用此委托,可以依次调用所有绑定的方法

    不积跬步,无以至千里;不积小流,无以成江海。ヾ(◍°∇°◍)ノ゙
  • 相关阅读:
    使用尾递归对斐波那契优化?
    Ajax是什么?包含什么技术?有什么作用?
    Ajax的乱码解决问题?
    Ajax的核心的对象是什么?
    为什么Java中不支持多重继承?
    vue-router的原理,例如hashhistory和History interface?
    JSP是什么?有什么特点?
    forward 和redirect的区别?
    Listener是什么?有什么作用?
    请说一说Servlet的生命周期?
  • 原文地址:https://www.cnblogs.com/jiangxianshen/p/15292388.html
Copyright © 2011-2022 走看看