C#委托讲解以及示例演示

什么是委托

通俗解释:委托就是一个能存放符合某种格式(方法签名)的方法的指针
自己理解:委托就是定义一个变量来存放方法,这个委托可以存放多个方法,在调用的时候,会按照添加的次序来执行添加的方法

对委托的理解

其实委托类似于C语言中的指针,他是一种数据类型的名字,例如int、double等,只不过,指针类型存放的是方法。
委托本身就是一个类,可以写在类的里面或者类的外边,本身是一个语法糖,在编译的时候会编译成一个类。

委托的作用

因为委托是一个存放方法的数据类型,所以委托的作用如下
  1. 将方法作为参数
  2. 将方法作为返回值
  3. 将方法作为外部属性

使用委托

因为委托本身就是一个类,在使用的时候需一下几个步骤
  1. 声明委托
  2. 创建委托对象
  3. 调用委托

*委托示例

1.排序

现有一个Dog类,这个Dog类属性有 Name、Age 如下:

    public class Dog
    {
        private string name;
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

        private int age;
        public int Age
        {
            get { return age; }
            set { age = value; }
        }
    }

为这个Dog类创建多个对象,并存放在List的泛型中,如下:

            List<Dog> list = new List<Dog>();

            list.Add(new Dog() { Name = "小黑", Age = 12 });
            list.Add(new Dog() { Name = "小绿", Age = 2 });
            list.Add(new Dog() { Name = "小白", Age = 22 });
            list.Add(new Dog() { Name = "小青", Age = 34 });

需求:现在需要为这个泛型集合中的小狗狗们按照年龄进行排序,目前有两种解决方案,1.使用接口;2.使用委托;3.使用lamda表达式

在List集合中,有一个排序的方法Sort(),具有4个重载,分别如下:

  1. public void Sort();
  2. public void Sort(Comparison<T> comparison);
  3. public void Sort(IComparer<T> comparer);
  4. public void Sort(int index, int count, IComparer<T> comparer);
在这里,1,4,不进行阐述,主要讲解2,3


1.使用接口进行排序。

public void Sort(IComparer<T> comparer);

这个方法就是使用接口实现对对象进行排序


讲解:

IComparer是一个接口,其接口会实现一个Compare方法,来指定排序的条件,接口定义如下:

    // 摘要: 
    //     定义类型为比较两个对象而实现的方法。
    //
    // 类型参数: 
    //   T:
    //     要比较的对象的类型。
    public interface IComparer<in T>
    {
        // 摘要: 
        //     比较两个对象并返回一个值,指示一个对象是小于、等于还是大于另一个对象。
        //
        // 参数: 
        //   x:
        //     要比较的第一个对象。
        //
        //   y:
        //     要比较的第二个对象。
        //
        // 返回结果: 
        //     一个带符号整数,它指示 x 与 y 的相对值,如下表所示。值含义小于零x 小于 y。零x 等于 y。大于零x 大于 y。
        int Compare(T x, T y);
    }

那么,在使用接口的时候,我们要定义一个类CompareDog,来继承这个接口,并且设定排序的条件是按照对象中的年龄属性进行排序的,代码如下:

    public class CompareDog:IComparer<Dog>
    {
        public int Compare(Dog x, Dog y)
        {
            return x.Age - y.Age;
        }
    }

这样的话,我们就可以使用Sort(IComparer<T> comparer)这个方法来对集合进行排序了,这里的参数就是我们上边定义的CompareDog类,它实现了IComparer接口。

list.Sort(new CompareDog());//这样既实现了对集合的排序

2.使用委托排序

public void Sort(Comparison<T> comparison);

这个方法就是使用委托对集合进行排序

讲解:
Comparison其实就是一个委托类型,定义如下:
    // 摘要: 
    //     表示比较同一类型的两个对象的方法。
    //
    // 参数: 
    //   x:
    //     要比较的第一个对象。
    //
    //   y:
    //     要比较的第二个对象。
    //
    // 类型参数: 
    //   T:
    //     要比较的对象的类型。
    //
    // 返回结果: 
    //     一个有符号整数,它指示 x 与 y 的相对值,如下表所示。值含义小于 0x 小于 y。0x 等于 y。大于 0x 大于 y。
    public delegate int Comparison<in T>(T x, T y);

既然是委托类型的参数,那么我们就要写一个符合该委托的方法,并指定排序的条件,代码如下:
        int Comparison(Dog x, Dog y)
        {
            return x.Age - y.Age;
        }

这样,我们在排序的时候,只需要将上边的这个方法传入作为参数即可:
list.Sort(Comparison);

3.使用lamda表达式排序

其实,lamda表达式的本质就是一个委托,只不过微软把它变成了语法糖,方便程序员的使用,这里不多阐述,代码如下即可实现:
list.Sort((x,y)=>x.Age-y.Age);


2.求最大值

要求:有一个int型的数组,求其中的最大值

我们先按照常规的思想来做,然后在使用委托实现。


 int[] arrInt = new int[5] { 1,3,8,4,2};

常规思想:

定义一个方法,传入这个数组作为参数,然后循环遍历该数组,取出最大值,方法如下:

        int MaxInt(int[] arr)
        {
            int maxInt = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                if (maxInt < arr[i])
                {
                    maxInt = arr[i];
                }
            }
            return maxInt;
        }

调用:

            int[] arrInt = new int[5] { 1,3,8,4,2};
            int max = MaxInt(arrInt);


注:以上自定义的方法可以实现求int型数据的最大值,那么如果求double型的最大值?string类型的字符串长度?对象中按照指定的属性求最大值?  这样的话就得针对每一种情况都要写一个方法,从逻辑上是可以实现的,但是使用委托会是一种更好的方法。


委托实现

定义一个泛型方法,传入数组作为参数,同时传入Comparison<T>类型作为比较的委托,这个委托在上边已经讲解过,代码如下:

       T MaxValue<T>(T[] arr,Comparison<T> func)
        {
            T maxInt = arr[0];
            for (int i = 1; i < arr.Length; i++)
            {
                //使用委托来比较
                if (func(maxInt, arr[i]) < 0)
                {
                    maxInt = arr[i];
                }
            }
            return maxInt;
        }

调用:这里的委托方法参数使用lamda表达式表示

            //求最大数
            int[] arrInt = new int[5] { 1,3,8,4,2};
            int max = MaxValue<int>(arrInt, (x, y) => x - y);

            //求字符串长度最大的字符串
            string[] arrStr = new string[] { "aa","fcc","tgtgc"};
            string maxLenght = MaxValue<string>(arrStr, (x, y) => x.Length - y.Length);

            //按照年龄,求对象集合中年龄最大的对象
            Dog[] dogs = new Dog[] { new Dog() { Name = "小黑", Age = 12 }, new Dog() { Name = "小lv", Age = 2 }, new Dog() { Name = "小bai", Age = 62 }, new Dog() { Name = "小qing", Age = 22 } };
            Dog maxDog = MaxValue<Dog>(dogs, (x, y) => x.Age - y.Age);


不喜勿喷,欢迎评论!


C#委托讲解以及示例演示

上一篇:Windows+ubuntu双系统


下一篇:C# 标签(条码)的打印与设计(二)