.net高级技术——委托、泛型委托和内置泛型委托

1.什么是委托?

委托是一种可以指向方法的数据类型,可以声明委托类型变量

声明委托的方式,使用delegate关键值来声明。

具体格式:delegate 返回值类型  委托类型名(参数)

例:delegate int MyDelegate(int a,string b)

2.那么如何去创建一个委托类型的对象呢:MyDelegate demoDel = new MyDelegate(SayHello);

下面的写法是错误的:MyDelegate demoDel = new MyDelegate(SayHello());因为这样写表示是调用方法。

但是可以使用下面的简便方法来创建委托类型对象:MyDelegate demoDel =SayHello;虽然你使用这种简便方法进行创建,但是

编译器会自动给你编译成第一种MyDelegate demoDel = new MyDelegate(SayHello);

class Program
    {
        static void Main(string[] args)
        {
            Mydelegate mydelegate = new Mydelegate(SayHello);
            mydelegate("张三");
            Console.ReadKey();
        }
        public static  int SayHello(string name )
        {
            Console.WriteLine(name+"你好呀");
            return 1;
        }
    }
    delegate int Mydelegate(string name); 

上述结果出来非常简单:张三你好呀

如果我们在上面代码段中加入下列的代码,就会发生错误,抛出异常

 mydelegate = null;
 mydelegate("报错");

3.下面我们用一个实际的例子来看看实际中怎么使用委托

要比较一个数组中的最大值,最后打印出最大值

 public class Test
    {
        public static void Main(string[] args)
        {
            int[] nums = { 5, 23, 3, 323, 3543, 21423, 214 };
            Console.WriteLine("最大值为" + GetMax(nums));
            Console.ReadKey();
        }
        public static int GetMax(int[] nums)
        {
            int max=nums[0];
            for (int i = 1; i < nums.Length; i++)
            {
                if(nums[i]>max)
                {
                    max = nums[i];
                }
            }
            return max;
        }
    }

上面这个方法只能查找整型数组的最大值,不利于扩展,如果我们要比较float、Double、或者自定义类的比较该怎么办呢??

下面我们使用委托来解决这个问题。

我们发现这个不同类型使用的比较最大值的方法都是差不多的,只是在比较前不知道要传入什么类型的数据,所以我们在比较的时候使用委托来解决。

    public class Test
    {
       
        public static void Main(string[] args)
        {
            object[] nums = { 11, 2, 2, 3, 34, 3, 543, 5, 251, 234 };
            CompareNum cpn = new CompareNum(CompareNum);
            int max = (int)GetMax(nums, cpn);
            Console.WriteLine(max);
            Console.ReadKey();
        }
        /// <summary>
        /// 用于比较整型数据的方法
        /// </summary>
        /// <param name="obj1"></param>
        /// <param name="obj2"></param>
        /// <returns></returns>
        public static bool CompareNum(object obj1, object obj2)
        {
            int num1 = (int)obj1;
            int num2 = (int)obj2;
            return num1 > num2;
        }
        public static object GetMax(object[] nums, CompareNum cpn)
        {
            object max = nums[0];
            for (int i = 1; i < nums.Length; i++)
            {
                if (!cpn(max, nums[i]))
                {
                    max = nums[i];
                }
            }
            return max;
        }
    }
    public delegate bool CompareNum(object obj1, object obj2);

上面的方法就是经过改造的版本,接下来我们扩展一个Double类型和Person类比较age的方法

        /// <summary>
        /// 用于比较Double类型数据
        /// </summary>
        /// <param name="obj1"></param>
        /// <param name="obj2"></param>
        /// <returns></returns>
        public static bool CompareNumDouble(object obj1, object obj2)
        {
            Double num1 = (Double)obj1;
            Double num2 = (Double)obj2;
            return num1 > num2;
        }

Main方法内容

            CompareNum cpn = CompareNumDouble;
            object[] nums = { 11.2, 2.2, 2.34, 3.34, 0.34, 2.3, 23.543, 2134.5, 4.251,3.234 };
            Double max = (Double)GetMax(nums, cpn);
            Console.WriteLine(max);
            Console.ReadKey();

运行结果:2134.5

接下来我们写Person类

    public class Person
    {
        public int Age { get; set; }
        public string Name { get; set; }
        
    }

写入比较Person类Age属性的方法

 /// <summary>
        /// 用于Person类比较方法
        /// </summary>
        /// <param name="obj1"></param>
        /// <param name="obj2"></param>
        /// <returns></returns>
        public static bool CompareNumPerson(object obj1, object obj2)
        {
            Person num1 = (Person)obj1;
            Person num2 = (Person)obj2;
            return num1.Age > num2.Age;
        }

最后在Main方法中测试

         Person[] p1 = { new Person() { Age = 12, Name = "张三" }, new Person() { Age = 32, Name = "李四" }, new Person() { Age = 22, Name = "王五" } };
            CompareNum cpn = new CompareNum(CompareNumPerson);
            Person maxPerson = (Person)GetMax(p1, cpn);
            Console.WriteLine("最大年龄的人是"+maxPerson.Name+"年龄为"+maxPerson.Age);
            Console.ReadKey();

结果为:最大年龄的人是李四年龄为32

在上面的例子中,我们对于GetMax方法没有做任何的改变,只是添加了对应类型的比较方法

4.委托与泛型结合

        public static T GetMax<T>(T[] nums, CompareNum<T> cpn)
        {
            T max = nums[0];
            for (int i = 1; i < nums.Length; i++)
            {
                if (!cpn(max, nums[i]))
                {
                    max = nums[i];
                }
            }
            return max;
        }
    }
    public delegate bool CompareNum<T>(T obj1, T obj2);

会产生同样的结果

5.Func和Action

在平时的时候,一般不需要我们自己去写泛型委托,.Net中内置两个泛型委托Func、Action(在“对象浏览器”的mscorlib的System下),日常开发中基本不用自定义委托类型了。

我们用Func、 Action代替之前的委托

Action是带返回值的,Func是无返回值的

  class Program
    {
        public static void Main(string[] args)
        {
            Func<string, string> func = new Func<string, string>(PrintName);
            Console.WriteLine(func("里斯u"));
            Console.ReadKey();
            
        }
        public static string PrintName(string name)
        {
            return name;
        }
    }
        public static void Print(string name)
        {
            Console.WriteLine(name);
        }
            Action<string> act = new Action<string>(Print);
            Print("潇洒回复");
            Console.ReadKey();

---本博客是学习以后记录知识,如有侵权,请联系删除!!!

猜你喜欢

转载自blog.csdn.net/qq_33407246/article/details/88855829