using System;
  
 delegate double DoCalculate(double num);
  
 class RocketCalculator
 { 
 
     private DoCalculate[] calculations;
     private int calculationCounter;
      
     public RocketCalculator()
     { 
 
         calculationCounter = 0;
         calculations = new DoCalculate[10];
     }
      
     public void AddCalculation(DoCalculate newCalculation)
     { 
 
         calculations[calculationCounter] = newCalculation;
         calculationCounter++;
     }
      
     public double StartCalculation(double tempValue)
     { 
 
         Console.WriteLine("Start value: {0}", tempValue);   
         for (int i = 0; i < calculationCounter; i++)
         { 
 
             tempValue = calculations[i](tempValue);       
         }
         return tempValue;
     }
 }
  
 class Math
 { 
 
     public static DoCalculate DoMinusTwenty = new DoCalculate(MinusTwenty);
     public static DoCalculate DoTimesTwo = new DoCalculate(TimesTwo);
     public static DoCalculate DoPlusTen = new DoCalculate(PlusTen);
  
     public static double MinusTwenty(double number)
     { 
 
         Console.WriteLine("Minus twenty");
         return number - 20;
     }
      
     public static double TimesTwo(double number)
     { 
 
         Console.WriteLine("Times two");
         return number * 2;
     }
     
     public static double PlusTen(double number)
     { 
 
         Console.WriteLine("Plus ten");
         return number + 10;
     }  
 }public class Tester
 { 
 
     public static void Main()
     { 
 
         double startValue;
         double endResult;
         string response;
         
         RocketCalculator calculator = new RocketCalculator();
         
         Console.Write("Enter start value: ");
         startValue = Convert.ToDouble(Console.ReadLine());
         Console.WriteLine("Create sequence of operations by repeatedly");
         Console.WriteLine("choosing from the following options");
         Console.WriteLine("M)inus twenty");
         Console.WriteLine("T)imes two");
         Console.WriteLine("P)lus ten");
         Console.WriteLine("When you wish to perform the calculation enter C\n");
         
         do
         { 
 
             response = Console.ReadLine().ToUpper();
             switch(response)
             { 
 
                 case "M":
                     calculator.AddCalculation(Math.DoMinusTwenty);
                     Console.WriteLine("Minus twenty operation added");
                 break;
                 case "T":
                     calculator.AddCalculation(Math.DoTimesTwo);
                     Console.WriteLine("Times two operation added");
                 break;
                 case "P":
                     calculator.AddCalculation(Math.DoPlusTen);
                     Console.WriteLine("Plus ten operation added");
                 break;
                 case "C":
                     endResult = calculator.StartCalculation(startValue);
                     Console.WriteLine("End result: {0}", endResult);
                 break;
                 default:
                     Console.WriteLine("Invalid choice please try again");
                 break;
             }
         } while (response != "C");
     }
 }

 
这是这个例子的代码。(好废话哦~~)

不过还真是够长的,它做了些什么呢?模拟了火箭发射吗?哈哈,肯定不可能,还没这么强。其实也就是借用了Rocket这个大名号做了一些简单的操作(计算)。如类的名字所展示的,它包含两个主要类 -  关于火箭计算的类和用于提供数学方法的类(当然还有一个用于测试的类)。

从上看下来,第三行我们就见到了我们的主题 - 委托。这个一个委托的定义,返回值跟参数要跟使用它封装的方法一致。

然后在RocketCalculator类里我们声明了一个委托数组,在类的构造器里把它实例化为长度为10的数组(当然这个长度是任意取的)。

然后我们跳到Math类,可以看到定义了3个静态方法,并把这三个方法用3个委托封装起来了,委托的名称直观得说明了方法的用途。

在Tester类里,我们实例化了RocketCalculator类,并且定义了一个的初始值,并且使用ReadLine()等待用户为它赋值。

在do循环里,我们等待用户输入一个命令,对初始值进行操作(这里有三种操作:减20,乘2和加10)。

一旦接受了一个命令,然后把这个命令送到了我们的火箭计算器里:)(怎么送呢?如代码所示,使用calculator.AddCalculation())。AddCalculation接受到一个DoCalculate类型的委托,然后保存在委托数组里。

用户发出开始指令后,calculator.StartCalculation()接受刚开始指定的初始值就开始计算了。

恩~~~有哪些计算呢?呵呵,我们不是都已经保存在委托数组里了嘛,OK!Go!

马上,我们的结果就出来了。

其实这是对一些复杂模拟程序的简单化版本。我们有一些操作(方法),然后用委托封装了起来,然后使用统一的规格使用,挺方便的。

当然,如果是没有返回值的方法,我们可以用组播委托,那么委托数组都不用了。暂时不介绍了,下次再写:)

PS:
1.在OOP术语中,类指源代码中定义的类,而在运行时期间进行“实例化”的称作一个对象。但值得注意的是,委托没有与之相似的术语。“委托”定义和委托的“实例化”均称作委托。
2.我个人认为委托就是完成了对方法的一种封装,使其规格统一(有统一的名称),以利于抽象。至于CallBack,我正在理解中:(。
3.这只是一个委托的一个简单介绍,并不涉及委托更深层次的问题,以后再写吧。
4.此文参考了《C# Primer Plus》( 这真是一本好书,我推荐所有C#的初学者去买,你学到的不将只是C#语法)。 
posted on 2004-11-16 20:01 小新0574 阅读(101) 评论(3)  编辑 收藏 

Feedback
# re: 使用委托数组的一个例子简介一下委托 2004-11-16 20:33 Allen Lee 
代码改进一下:

class RocketCalculator
 { 
 
     private DoCalculate[] calculations;    public bool AddCalculation(DoCalculate newCalculation)
     { 
 
         if (calculationCounter < 10)
         { 
 
             calculations[calculationCounter] = newCalculation;
             calculationCounter++;            return true;
         }
         else
         { 
 
             return false;
         }
     }    // other code 
 }

说明,由于你使用定长数组来储存委托,AddCalculation里面应该检测数组是否越界,并返回true或false来说明添加是否成功。或者,你也可以改用collection类作为储存工具。