利用委托的一个实例-----BubbleSorter示例

下面的例子实现的功能是:根据雇员的薪水大小实现对雇员的排序,用面向对象的观点看就是:根据对象的一个属性实现对对象的排序.
下面的示例将说明委托的用途。我们要编写一个类BubbleSorter,它执行一个静态方法Sort(),这个方法的第一个参数是一个对象数组,把该数组按照升序重新排列。换言之,假定传递的是int数组:{0, 5, 6, 2, 1},则返回的结果应是{0, 1, 2, 5, 6}。
冒泡排序算法非常著名,是一种排序的简单方法。它适合于一小组数字,因为对于大量的数字(超过10个),还有更高效的算法。冒泡排序算法重复遍历数组,比较每一对数字,按照需要交换它们的位置,把最大的数字逐步移动到数组的最后。对于给int排序,进行冒泡排序的方法如下所示:
   for (int i = 0; i < sortArray.Length; i++)
   {
      for (int j = i + 1; j < sortArray.Length; j++)
      {
         if (sortArray[j] < sortArray[i])   // problem with this test
         {
            int temp = sortArray[i];   // swap ith and jth entries
            sortArray[i] = sortArray[j];
            sortArray[j] = temp;
         }
      }
   }
它非常适合于int,但我们希望Sort()方法能给任何对象排序。换言之,如果某段客户机代码包含Currency结构数组或其他类和结构,就需要对该数组排序。这样,上面代码中的if(sortArray[j] < sortArray[i])就有问题了,因为它需要比较数组中的两个对象,看看哪一个更大。可以对int进行这样的比较,但如何对直到运行期间才知道或确定的新类进行比较?答案是客户机代码知道类在委托中传递的是什么方法,封装这个方法就可以进行比较。
定义如下的委托:
   delegate bool CompareOp(object lhs, object rhs);
给Sort方法指定下述签名:
   static public void Sort(object [] sortArray, CompareOp gtMethod)
这个方法的文档说明强调,gtMethod必须表示一个静态方法,该方法带有两个参数,如果第二个参数的值“大于”第一个参数(换言之,它应放在数组中靠后的位置),就返回true。
注意:
这里使用的是委托,但也可以使用接口来解决这个问题。.NET提供的IComparer接口就用于此目的。但是这里使用委托是因为这种问题本身要求使用委托。
设置完毕后,下面定义类BubbleSorter:
   class BubbleSorter
   {
      static public void Sort(object [] sortArray, CompareOp gtMethod)
      {
         for (int i=0 ; i<sortArray.Length ; i++)
         {
            for (int j=i+1 ; j<sortArray.Length ; j++)
            {
               if (gtMethod(sortArray[j], sortArray[i]))
               {
                  object temp = sortArray[i];
                  sortArray[i] = sortArray[j];
                  sortArray[j] = temp;
               }
            }
         }
      }
   }
为了使用这个类,需要定义一些其他类,建立要排序的数组。在本例中,假定Mortimer Phones移动电话公司有一个员工列表,要对照他们的薪水进行排序。每个员工分别由类Employee的一个实例表示,如下所示:
   class Employee
   {
      private string name;
      private decimal salary;
 
      public Employee(string name, decimal salary)
      {
         this.name = name;
         this.salary = salary;
      }
 
      public override string ToString()
      {
         return string.Format(name + ", {0:C}", salary);
      }
 
      public static bool RhsIsGreater(object lhs, object rhs)
      {
         Employee empLhs = (Employee) lhs;
         Employee empRhs = (Employee) rhs;
         return (empRhs.salary > empLhs.salary) ? true : false;
      }
   }
注意,为了匹配CompareOp委托的签名,在这个类中必须定义RhsIsGreater,它的参数是两个对象引用,而不是Employee引用。必须把这些参数的数据类型转换为Employee引用,才能进行比较。
下面编写一些客户机代码,完成排序:
using System;
 
namespace Wrox.ProCSharp.AdvancedCSharp
{
   delegate bool CompareOp(object lhs, object rhs);
 
   class MainEntryPoint
   {
      static void Main()
      {
         Employee [] employees =
            {
               new Employee("Bugs Bunny", 20000),
               new Employee("Elmer Fudd ", 10000),
               new Employee("Daffy Duck", 25000),
               new Employee("Wiley Coyote", (decimal)1000000.38),
               new Employee("Foghorn Leghorn", 23000),
               new Employee("RoadRunner'", 50000)};
         CompareOp employeeCompareOp = new CompareOp(Employee.RhsIsGreater);
         BubbleSorter.Sort(employees, employeeCompareOp);
 
         for (int i=0 ; i<employees.Length ; i++)
            Console.WriteLine(employees[i].ToString());
      }
   }
运行这段代码,正确显示按照薪水排列的Employee,如下所示:
BubbleSorter
Elmer Fudd, $10,000.00
Bugs Bunny, $20,000.00
Foghorn Leghorn, $23,000.00
Daffy Duck, $25,000.00
RoadRunner, $50,000.00
Wiley Coyote, $1,000,000.38
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值