C#学习笔记(11)-委托

为什么要使用委托

需要将方法作为一个参数传递给另一个方法。
结合委托的概念,可以将以下代码:

        static void Main(string[] args)
        {
            //三个需求
            //1.将一个字符串数组中的每个元素都转换成大写
            //2.将一个字符串数组中的每个元素都转换成小写
            //3.将一个字符串数组中的每个元两边都加上双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
            //ProsToUpper(names);
            //ProsToLower(names);
            AddQuot(names);
            foreach (var item in names)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();
        }

        /// <summary>
        /// 转成大写
        /// </summary>
        /// <param name="name"></param>
        public static void ProsToUpper(string[] name)
        {
            for (int i = 0; i < name.Length; i++)
            {
                name[i] = name[i].ToUpper();
            }
        }

        /// <summary>
        /// 转成小写
        /// </summary>
        /// <param name="name"></param>
        public static void ProsToLower(string[] name)
        {
            for (int i = 0; i < name.Length; i++)
            {
                name[i] = name[i].ToLower();
            }
        }

        /// <summary>
        /// 加双引号
        /// </summary>
        /// <param name="name"></param>
        public static void AddQuot(string[] name)
        {
            for (int i = 0; i < name.Length; i++)
            {
                name[i] = "\"" + name[i] + "\"";
            }
        }

修改成:

        //在类内部声明一个委托
        //委托的语法:
        //1、访问权限;2、delegate关键字;3、返回值类型;4、委托名;5、参数列表
        public delegate string Str(string name);

        static void Main(string[] args)
        { 
            //三个需求
            //1.将一个字符串数组中的每个元素都转换成大写
            //2.将一个字符串数组中的每个元素都转换成小写            
            //3.将一个字符串数组中的每个元两边都加上双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
            StrPro(names, StrToUpper);
            foreach (var item in names)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();


        }

        public static void StrPro(string[] name,Str 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 StrAddQuto(string name)
        {
            return "\"" + name + "\"";
        }      

委托概念

函数的签名必须和委托的签名一致。
签名:函数的返回值类型和参数类型,数量

    //声明一个委托指向一个函数,必须和指向的函数签名相同
    //签名是指返回值和传入的参数
    public delegate void DelSayHi(string name);

    class Program
    {
        static void Main(string[] args)
        {
            DelSayHi del = new DelSayHi(SayHiChinese);
            del("张三");
            Console.ReadKey();
        }

        public static void SayHiChinese(string name)
        {
            Console.WriteLine("吃了吗?" + name);
        }

        public static void SayHiEnglish(string name)
        {
            Console.WriteLine("Nice to meet you!" + name);
        }

以下代码展示了委托如何将函数作为一个参数传递给另一个函数的。

//声明一个委托指向一个函数,必须和指向的函数签名相同
    //签名是指返回值和传入的参数
    public delegate void DelSayHi(string name);

    class Program
    {
        static void Main(string[] args)
        {
            //将函数作为参数传递给另一个函数
            Test("Lucy", SayHiEnglish);
            Console.ReadKey();
        }

        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、delegate关键字;3、返回值类型;4、委托名;5、参数列表
        public delegate string Str(string name);

        static void Main(string[] args)
        { 
            //三个需求
            //1.将一个字符串数组中的每个元素都转换成大写
            //2.将一个字符串数组中的每个元素都转换成小写            
            //3.将一个字符串数组中的每个元两边都加上双引号
            string[] names = { "abCDefG", "HIJKlmnOP", "QRsTuvW", "XyX" };
            //匿名函数
            //语法:1、delegate;2、参数列表;3、方法体。
            StrPro(names, delegate(string name)
            {
                return name.ToUpper();
            });

            foreach (var item in names)
            {
                Console.WriteLine(item);
            }
            Console.ReadKey();


        }

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

例子2:

        public delegate void SayHiDel(string name);

        static void Main(string[] args)
        {
            //delegate所声明的函数相当于是与SayHiDel签名一致的函数,可以直接赋值给这个委托
            //然后通过声明的委托调用这个函数
            SayHiDel del = delegate (string name)
              {
                  Console.WriteLine("您好!" + name);
              };
            del("张三");
            Console.ReadKey();
        }

泛型委托

求任意数组中的最大值,用object类型声明数组,其实现源码如下:

        //声明一个委托
        public delegate int DelCompare(object o1, object o2);

        static void Main(string[] args)
        {
            //求任意数组中的最大值
            object[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
            Console.WriteLine(GetMax(nums, Compare));
            Console.ReadKey();


        }

        //比较两个数大小,将更大值赋值给max
        public static object GetMax(object[] nums,DelCompare del)
        {
            object max = nums[0];
            for (int i = 1; i < nums.Length; i++)
            {
                if(del(max,nums[i])<0)
                {
                    max = nums[i];
                }
            }
            return max;
        }

        //比较两个数的大小
        public static int Compare(object o1,object o2)
        {
            int n1 = (int)o1;
            int n2 = (int)o2;
            return n1 - n2;
        }
  ```
  泛型委托的写法为:

    //声明一个委托
    public delegate int DelCompare<T>(T t1, T t2);

    static void Main(string[] args)
    {
        //求任意数组中的最大值
        int[] nums = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
        Console.WriteLine(GetMax<int>(nums, delegate(int n1,int n2)
        {
            return n1 - n2;
        }));
        Console.ReadKey();              
    }

    //比较两个数大小,将更大值赋值给max
    public static T GetMax<T>(T[] nums,DelCompare<T> del)
    {
        T max = nums[0];
        for (int i = 1; i < nums.Length; i++)
        {
            if(del(max,nums[i])<0)
            {
                max = nums[i];
            }
        }
        return max;
    }

#lamda表达式

语法1:

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

    static void Main(string[] args)
    {
        DelOne del = delegate () { };
        DelOne del1 = () => { };
        DelTwo del2 = (string name) => { };
        DelThree del3 = (string name) => { return name; };
    }

语法2:
        List<int> list = new List<int>() { 1, 2, 3, 4, 55, 6, 7, 8, 9 };
        //lamda表达式
        list.RemoveAll(n => n > 4);
        foreach (var item in list)
        {
            Console.WriteLine(item);
        }
        Console.ReadKey();

“`

猜你喜欢

转载自blog.csdn.net/lonesome_zxq/article/details/80713300