40.委托

什么是委托?

将一个方法作为参数传递给另一个方法。

注意:委托所指向的方法必须和委托具有相同的签名(返回值类型和参数列表)

举例

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2 {


    //声明一个委托指向一个函数
    public delegate void DelSayHi(string name);


    class Program {
        static void Main(string[] args) {
            //DelSayHi del = new DelSayHi(SayHiEnglish);
            //DelSayHi del = SayHiEnglish; //函数可以直接赋值给一个委托对象。前提:委托的签名必须和函数的签名一样。
            //del("张三");

            //将方法作为参数传给了另一个方法
            Test("张三", SayHiChinese);
            Console.ReadKey();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <param name="name"></param>
        /// <param name="del">参数是委托类型</param>
        public static void Test(string name, DelSayHi del) {
            //调用
            del(name);
        }

        public static void SayHiChinese(string name) {
            Console.WriteLine("吃了么?" + name);
        }
        public static void SayHiEnglish(string name) {
            Console.WriteLine("Nice to meet you" + name);
        }
    }
}

运行:

举例

现在有三个需求:
1、将一个字符串数组中每个元素都转换成大写
2、将一个字符串数组中每个元素都转换成小写
3、将一个字符串数组中每个元素两边都加上 双引号

原始版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2 {


   
    class Program {
        static void Main(string[] args) {
            //三个需求
            //1、将一个字符串数组中每个元素都转换成大写
            //2、将一个字符串数组中每个元素都转换成小写
            //3、将一个字符串数组中每个元素两边都加上 双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyZ" };
            //ProStToUpper(names);
            //ProStrToLower(names);
            ProStrSYH(names);

            for (int i = 0; i < names.Length; i++) {
                Console.WriteLine(names[i]);
            }


            Console.ReadKey();
        }

        


        public static void ProStToUpper(string[] name) {
            for (int i = 0; i < name.Length; i++) {
                name[i] = name[i].ToUpper();
            }
        }
        public static void ProStrToLower(string[] name) {
            for (int i = 0; i < name.Length; i++) {
                name[i] = name[i].ToLower();
            }
        }
        public static void ProStrSYH(string[] names) {
            for (int i = 0; i < names.Length; i++) {
                names[i] = "\"" + names[i] + "\"";
            }
        }


    }
}

运行结果:

委托版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2 {


    //声明一个委托指向一个函数
    public delegate string DelProStr(string name);
    class Program {
        static void Main(string[] args) {
            //三个需求
            //1、将一个字符串数组中每个元素都转换成大写
            //2、将一个字符串数组中每个元素都转换成小写
            //3、将一个字符串数组中每个元素两边都加上 双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyZ" };

            ProStr(names, StrToUpper);
            //ProStr(names, StrToLower);
            //ProStr(names, StrSYH);

            for (int i = 0; i < names.Length; i++) {
                Console.WriteLine(names[i]);
            }

            Console.ReadKey();
        }


        public static void ProStr(string[] name, DelProStr del) {
            for (int i = 0; i < name.Length; i++) {
                name[i] = del(name[i]);
            }
        }

        public static string StrToUpper(string name) {
            return name.ToUpper();
        }

        public static string StrToLower(string name) {
            return name.ToLower();
        }

        public static string StrSYH(string name) {
            return "\"" + name + "\"";
        }

    }
}

运行:

匿名函数版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2 {


    //声明一个委托指向一个函数
    public delegate string DelProStr(string name);
    class Program {
        static void Main(string[] args) {
            //三个需求
            //1、将一个字符串数组中每个元素都转换成大写
            //2、将一个字符串数组中每个元素都转换成小写
            //3、将一个字符串数组中每个元素两边都加上 双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyZ" };

            ProStr(names, delegate (string name) {
                return name.ToUpper();
            });
            
            for (int i = 0; i < names.Length; i++) {
                Console.WriteLine(names[i]);
            }



            Console.ReadKey();
        }


        public static void ProStr(string[] name, DelProStr del) {
            for (int i = 0; i < name.Length; i++) {
                name[i] = del(name[i]);
            }
        }        

    }
}

运行:

匿名函数:当方法只执行一次时可以考虑写成匿名函数。

lamda表达式版

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp4 {
    //声明一个委托指向一个函数
    public delegate string DelProStr(string name);
    class Program {
        static void Main(string[] args) {
            //三个需求
            //1、将一个字符串数组中每个元素都转换成大写
            //2、将一个字符串数组中每个元素都转换成小写
            //3、将一个字符串数组中每个元素两边都加上 双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyZ" };

            ProStr(names, (name)=> {
                return name.ToUpper();
            });

            for (int i = 0; i < names.Length; i++) {
                Console.WriteLine(names[i]);
            }



            Console.ReadKey();
        }


        public static void ProStr(string[] name, DelProStr del) {
            for (int i = 0; i < name.Length; i++) {
                name[i] = del(name[i]);
            }
        }

    }
}

运行:

泛型委托

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp2 {

    //泛型委托
    public delegate int DelCompare<T>(T t1, T t2);
    // public delegate int DelCompare(object o1, object o2);
    class Program {
        static void Main(string[] args) {
            int[] nums = { 1, 2, 3, 4, 5 };
            int max = GetMax<int>(nums, Compare1);
            Console.WriteLine(max);

            string[] names = { "abcdefg", "fdsfds", "fdsfdsfdsfdsfdsfdsfdsfsd" };
            string max1 = GetMax<string>(names, (string s1, string s2) => {
                return s1.Length - s2.Length;
            });
            Console.WriteLine(max1);
            Console.ReadKey();
        }

        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="nums"></param>
        /// <param name="del"> 泛型委托</param>
        /// <returns></returns>
        public static T GetMax<T>(T[] nums, DelCompare<T> del) {
            T max = nums[0];
            for (int i = 0; i < nums.Length; i++) {
                //要传一个比较的方法
                if (del(max, nums[i]) < 0) {
                    max = nums[i];
                }
            }
            return max;
        }


        public static int Compare1(int n1, int n2) {
            return n1 - n2;
        }
    }
}

运行:

lamda表达式

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp3 {

    public delegate void DelOne();
    public delegate void DelTwo(string name);
    public delegate string DelThree(string name);

    class Program {
        static void Main(string[] args) {
            //DelOne delOne = delegate () { };
            DelOne delOne = () => { };

            //DelTwo delTwo = delegate(string name){ };
            DelTwo delTwo = (string name) => { };

            //DelThree delThree = delegate(string name) { return name; };
            //DelThree delThree = (string name) => { return name; };
            //或者string也可以不写
            DelThree delThree = (name) => { return name; };

            List<int> list = new List<int>() { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            list.RemoveAll(n => n > 4);
            foreach (var item in list) {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }
    }
}

运行:

使用委托进行窗体传值

效果

实现

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp9 {
    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e) {
            Form2 form2 = new Form2(ShowMsg);
            form2.Show();
        }

        void ShowMsg(string str) {
            label1.Text = str;
        }
    }
}

再创建Form2窗体

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp9 {
    //声明一个委托
    public delegate void DelTest(string str);

    public partial class Form2 : Form {
        public DelTest _del;

        public Form2(DelTest del) {
            this._del = del;
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e) {

            _del(textBox1.Text);
            
        }
    }
}

多播委托

委托布局指向一个函数,也可指向多个函数

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ConsoleApp4 {
    public delegate void DelTest();
    class Program {
        static void Main(string[] args) {
            DelTest del = T1;
            del += T2;
            del += T3;
            del += T4;
            del -= T3;
            del -= T1;
            del();
            Console.ReadKey();
        }

        public static void T1() {
            Console.WriteLine("我是T1");
        }
        public static void T2() {
            Console.WriteLine("我是T2");
        }

        public static void T3() {
            Console.WriteLine("我是T3");
        }
        public static void T4() {
            Console.WriteLine("我是T4");
        }
    }
}
运行:
![](https://img2020.cnblogs.com/blog/1773322/202005/1773322-20200528233306296-1486149401.png)

posted @ 2020-05-28 23:33  兔子不会吃草  阅读(173)  评论(0编辑  收藏  举报