最近在看C#,以前学习VC的时候没有委托的概念,用的都是回调函数,现在正好学习一下。
概念
和回调差不多,都是在对象或者过程中定义一个类似的“接口”,然后在后边写清楚这个接口的具体实现。但是委托的功能回调函数强大太多了。
实现方法
1)在类的定义里,首先定义一个公开的委托类型。
public delegate void XXXHandler(XXX XXXX);
2)定义每个委托类型的成员变量。
private XXXHandler listOfHandler;
3)向调用者添加注册函数
public void RegisterXXXX(XXXHandler methodToCall)
{
listOfHandler += methodToCall;
}
4) 在需要用的时候,new一个XXXHandler对象,并将处理的函数作为参数指定给该对象
xx.RegisterXXXX(new xx.XXXHandler(XXXXEvent)); //这里XXXEvent是定义在外部的处理函数
代码
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace test3
{
public class Car
{
public int CurrentSpeed { get; set; }
public int MaxSpeed { get; set; }
public string PetName{ get; set; }
private bool carIsDead;
public Car() { MaxSpeed = 100; }
public Car( string name, int maxSp, int currSp)
{
CurrentSpeed = currSp;
MaxSpeed = maxSp;
PetName = name;
}
public delegate void CarEngineHandler(string msgForCaller);
private CarEngineHandler listOfHandlers;
public void RegisterWithCarEngine(CarEngineHandler methodToCall)
{
listOfHandlers += methodToCall; //用+=就可以支持多路的广播了,而不是用=, Remove:-=
}
public void UnRegisterWithCarEngine(CarEngineHandler methodToCall)
{
listOfHandlers -= methodToCall;
}
public void Accelerate(int delta)
{
if (carIsDead)
{
if (listOfHandlers != null)
{
listOfHandlers("Sorry, this car is dead ...");
}
}
else
{
CurrentSpeed += delta;
if (10 == (MaxSpeed - CurrentSpeed) && listOfHandlers != null)
{
listOfHandlers("Careful buddy! Gonna blow!");
}
if (CurrentSpeed >= MaxSpeed)
carIsDead = true;
else
Console.WriteLine("CurrentSpeed = {0}", CurrentSpeed);
}
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine("**** Delegates as event enablers ******\n");
Car c1 = new Car("SlugBug", 100, 10);
Car.CarEngineHandler handler1 = new Car.CarEngineHandler(OnCarEngineEvent);
c1.RegisterWithCarEngine(handler1);
Car.CarEngineHandler handler2 = new Car.CarEngineHandler(OnCarEngineEvent2);
c1.RegisterWithCarEngine(handler2);
Console.WriteLine("**** Speeding up *****");
for(int i = 0; i< 6;i ++)
{
c1.Accelerate(20);
}
Console.ReadLine();
c1.UnRegisterWithCarEngine(handler2);
Console.WriteLine("****** Speeding up*******");
for(int i = 0; i<6; i++)
{
c1.Accelerate(20);
}
Console.ReadLine();
}
public static void OnCarEngineEvent(string msg)
{
Console.WriteLine("\n ******** Message From Car Object *********");
Console.WriteLine(" => {0}", msg);
Console.WriteLine("******************\n");
}
public static void OnCarEngineEvent2(string msg)
{
Console.WriteLine("=>{0}", msg.ToUpper());
}
}
}
其他
委托不仅支持多路广播(通过+=),还支持泛型,因暂时用不着,用到的时候再看吧。