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");
}
}
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#语法)。