【从码农到程序员】使用委托让代码更优雅

很多繁杂的代码可以用委托去优雅的实现同样的功能。

委托:寻址方法的.NET版本,类似于C++中的指针,区别在于类型安全,定于的返回类型和参数类型。委托是对方法引用。

定义委托

两个string类型的参数、返回值为string类型

public delegate string GetString(string a,string b);

Action<T>和Func<T>委托

泛型Action<T>委托表示引用一个void返回类型的方法。

Func<T>允许调用带返回类型的方法。PS: Func<int,int,bool> 是引用一个带两个整型参数,返回布尔类型的方法

适合使用委托的情况

我们使用冒泡排序对一组int型值进行排序,代码如下

 1         public static void Sort(int[] arr)
 2         {
 3             for (int i = 0; i < arr.Length - 1; i++)
 4             {
 5                 for (int j = 0; j < arr.Length - 1 - i; j++)
 6                 {
 7                     if (arr[j] > arr[j + 1])
 8                     {
 9                         int temp = arr[j];
10                         arr[j] = arr[j + 1];
11                         arr[j + 1] = temp;
12                     }
13                 }
14             }
15         }
View Code

但是如果我们希望Sort方法能给任何对象排序,目前的实现肯定无法满足。

比如一个Student对象,需要按照年龄排序

 1   class Student
 2   {
 3       public Student(string name, int age)
 4       {
 5           this.Name = name;
 6           this.Age = age;
 7       }
 8 
 9       public string Name { get; private set; }
10       public int Age { get; private set; }
11 
12       public override string ToString()
13       {
14           return string.Format("{0}, {1}", Name, Age);
15       }
16 
17       public static bool CompareAge(Student s1, Student s2)//年龄比较方法
18       {
19           return s1.Age < s2.Age;
20       }
21   }

可以将之扩展成一个泛型方法Sort<T>,需要有一个比较方法,比较两个T类型的参数,肯定不能使用“>”这种运算符去比较,这个方法可以Func<T1,T2,TResult>委托中引用,其中T1、T2的类型相同:Func<T,T,bool>

 1         static public void Sort<T>(IList<T> sortArray, Func<T, T, bool> comparison)
 2         {
 3 
 4             for (int i = 0; i < sortArray.Count - 1; i++)
 5             {
 6                 for (int j = 0; j < sortArray.Count - 1 - i; j++)
 7                 {
 8                     if (comparison(sortArray[j + 1], sortArray[j]))
 9                     {
10                         T temp = sortArray[j];
11                         sortArray[j] = sortArray[j + 1];
12                         sortArray[j + 1] = temp;
13                     }
14                 }
15             }
16 
17         }

测试调用方法:

 1             Student[] students = { 
 2                           new Student("Curry",34),
 3                           new Student("Lebron",23),
 4                           new Student("Kobe",24),                      
 5                           new Student("Yao",11)
 6                           };
 7             BubbleSorter.Sort(students, Student.CompareAge);
 8             foreach (var student in students)
 9             {
10                 Console.WriteLine(student);
11             }

 

委托还可以引用多个方法(多播委托),但是需要注意的是,其中一个方法异常,整个迭代就会停止;

匿名方法是将方法体直接赋予委托的一种委托创建方式,从C#3.0开始,可以使用Lamda表达式代替匿名方法;

事件基于委托,为委托提供了一种发布/订阅机制

posted @ 2016-04-03 19:36  RobertChan  阅读(477)  评论(0编辑  收藏  举报