• 委托应用及泛型委托和多播委托


    一、委托一般作为方法的参数或者返回值,或者使用多播委托(注册多个方法,可以全部触发)

    1.示例:根据对于字符串不同的处理方法逻辑
          private delegate void PrintString(string str);
    
            static void PrintStr( PrintString print,string str )
            {
                print(str);
            }
    
            static void Method1(string str) {
                Console.WriteLine(str);
            }
            static void Method2(string str)
            {
                Debug.WriteLine(str);
            }
     static void Main(string[] args)
    {
    
               PrintString method = Method1;
                PrintStr(method,"Test");
                method = Method2;
                PrintStr(method,"Test");
                Console.ReadKey();
    
    }
    

    二、泛型委托

    Action-Action<T>

       class Program {
            static void PrintString()
            {
                Console.WriteLine("hello world.");
            }
    
            static void PrintInt(int i)
            {
                Console.WriteLine(i);
            }
    
            static void PrintString(string str)
            {
                Console.WriteLine(str);
            }
    
            static void PrintDoubleInt(int i1, int i2)
            {
                Console.WriteLine(i1+i2);
            }
            static void Main(string[] args)
            {
                //Action a = PrintString;//action是系统内置(预定义)的一个委托类型,它可以指向一个没有返回值,没有参数的方法
                //Action<int> a=PrintInt;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个int参数的方法
                //Action<string> a = PrintString;//定义了一个委托类型,这个类型可以指向一个没有返回值,有一个string参数的方法 在这里系统会自动寻找匹配的方法
                Action<int, int> a = PrintDoubleInt;
                a(34, 23);
                Console.ReadKey();
                //action可以后面通过泛型去指定action指向的方法的多个参数的类型 ,参数的类型跟action后面声明的委托类型是对应着的
               
            }
        }
    

    Func<T>  

      class Program {
            static int Test1()
            {
                return 1;
            }
    
            static int Test2(string str)
            {
                Console.WriteLine(str);
                return 100;
            }
    
            static int Test3(int i, int j)
            {
                return i + j;
            }
            static void Main(string[] args)
            {
                //Func<int> a = Test1;//func中的泛型类型制定的是 方法的返回值类型
                //Console.WriteLine(a());
                //Func<string, int> a = Test2;//func后面可以跟很多类型,最后一个类型是返回值类型,前面的类型是参数类型,参数类型必须跟指向的方法的参数类型按照顺序对应
                Func<int, int, int> a = Test3;//func后面必须指定一个返回值类型,参数类型可以有0-16个,先写参数类型,最后一个是返回值类型
                int res = a(1, 5);
                Console.WriteLine(res);
                Console.ReadKey();
            }
        }
    

    泛型委托应用:冒泡排序扩展

    class Employee {
            public string Name { get; private set; }
            public int Salary { get; private set; }
    
            public Employee(string name, int salary)
            {
                this.Name = name;
                this.Salary = salary;
            }
            //如果e1大于e2的话,返回true,否则返回false
            public static bool Compare(Employee e1, Employee e2)
            {
                if (e1.Salary > e2.Salary) return true;
                return false;
            }
    
            public override string ToString()
            {
                return Name + ":" + Salary;
            }
        }
    View Code
       class Program {
            static void Sort(int[] sortArray)
            {
                bool swapped = true;
                do
                {
                    swapped = false;
                    for (int i = 0; i < sortArray.Length - 1; i++)
                    {
                        if (sortArray[i] > sortArray[i + 1])
                        {
                            int temp = sortArray[i];
                            sortArray[i] = sortArray[i + 1];
                            sortArray[i + 1] = temp;
                            swapped = true;
                        }
                    }
                } while (swapped);
            }
    
            static void CommonSort<T>(T[] sortArray, Func<T,T,bool>  compareMethod)
            {
                bool swapped = true;
                do {
                    swapped = false;
                    for (int i = 0; i < sortArray.Length - 1; i++) {
                        if (compareMethod(sortArray[i],sortArray[i+1])) {
                            T temp = sortArray[i];
                            sortArray[i] = sortArray[i + 1];
                            sortArray[i + 1] = temp;
                            swapped = true;
                        }
                    }
                } while (swapped);
            }
            static void Main(string[] args) {
                //int[] sortArray = new int[]{123,23,12,3,345,43,53,4};
                //Sort(sortArray);
                //foreach (var temp in sortArray)
                //{
                //    Console.Write(temp+" ");
                //}
                Employee[] employees = new Employee[]
                {
                    new Employee("dsf",12), 
                    new Employee("435dsf",234), 
                    new Employee("234dsf",14), 
                    new Employee("ds234f",234), 
                    new Employee("dssfdf",90)
                };
                CommonSort<Employee>(employees,Employee.Compare);
                foreach (Employee em in employees)
                {
                    Console.WriteLine(em);
                }
                Console.ReadKey();
            }
        }
    View Code

    多播委托:(可以注册多个方法给委托,也可以注销已注册的方法)

    方法:

         static void T1()
            {
                Console.WriteLine("ok");
            }
            static void T2()
            {
                Console.WriteLine("ook");
            }
            static void T3()
            {
                Console.WriteLine("oook");
            }
            static void M1(string msg)
            {
                Console.WriteLine(msg);
            }
            static void M2(string msg)
            {
                Console.WriteLine(msg);
            }
            static void M3(string msg)
            {
                Console.WriteLine(msg);
                Console.WriteLine("第3个方法。。");
            }
            static void M4(string msg)
            {
                Console.WriteLine(msg);
            }
            static void M5(string msg)
            {
                Console.WriteLine(msg);
            }
    View Code

    示例:

     class Program
        {
            static void Main(string[] args)
            {
                #region 多播委托
    
                ////一般第一个要使用=赋值,后续的方法可以使用+=来赋值。
                //Action<string> action = M1;
                //action += M2; //表示添加一个委托的引用 
                //action += M3;
                //action += M4;
                //action += M5;//action -= M3;//表示去除一个委托的引用
                if(action!=null){//防止为空,报错
                 action("xxx");//一次性触发全部的方法。调用顺序不一定哦。
    }
    //Console.ReadKey(); #endregion MyDelegate md = new MyDelegate(T1); //为什么这么写呢?等下取消注释上面的代码反编译之后放截图就知道 md = (MyDelegate)Delegate.Combine(md, new MyDelegate(T2), new MyDelegate(T3)); // md(); 下面的方法是获取所有注册的方法逐个调用 Delegate[] delegates = md.GetInvocationList(); for (int i = 0; i < delegates.Length; i++) { (delegates[i] as MyDelegate)(); } Console.ReadKey(); //使用队列试试 //Queue<MyDelegate> queue = new Queue<MyDelegate>(); //queue.Enqueue(new MyDelegate(T1)); //queue.Enqueue(T2); //queue.Enqueue(T3); //queue.Dequeue(); //queue.Dequeue(); //queue.Dequeue(); }

    多播委托反编译:可看到,本质就是调用Delegate.Combine方法组装起来的,调用的时候为什么能全部触发已注册的方法?可以看到编译器调用GetInvocationList方法之后得到委托父类数组循环逐个调用; 事件的本质我们稍后探讨,跟多播密不可分

  • 相关阅读:
    DFS搜索算法--(1)基础图遍历 绝对看!的!懂!
    C++;STL--队列与栈;
    Unity VR-播放demo模型后无法移动视角
    自律
    链表-简单练习题2-数据结构实验之链表二:逆序建立链表
    链表-简单练习题1-数据结构实验之链表一:顺序建立链表 SDUT2117
    链表--笔记
    leetcode--Binary Tree Maximum Path Sum
    leetcode--Single Number II
    leetcode--Single Number
  • 原文地址:https://www.cnblogs.com/entclark/p/7966765.html
Copyright © 2020-2023  润新知