1.什么是委托
  在C/C++中,有函数指针的概念,即指向函数的指针。当我们调用该指针时,相当于调用了该指针所指向的函数,这是函数指针的一个作用,而他另一个作用是将自己作为其他函数的参数。
  但是指针是直接访问内存单元的,程序员对指针的不恰当使用常常会引发错误。因此作为一门类型安全的语言,在一般情况下C#是不推荐使用指针的,比如使用函数指针作为参数时,你可以使用任何指针作为参数,因为他们都是32位的整型变量,不提供任何其他的信息,比如函数的参数个数,参数类型,返回值等。因此,在C#中有了委托的概念。
  我们首先来看一个简单的委托实例:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceDelegateTest
{
classprogram
{
delegatevoidMyDelegateTest(intx);
privatestaticvoidtest1(intx)
{
Console.WriteLine("输出平方"+(x*x));
}
privatestaticvoidtest2(intx)
{
Console.WriteLine("输出和"+(x+x));
}
staticvoidMain(string[]args)
{
inta=2;
MyDelegateTestdelegateTest;
delegateTest=newMyDelegateTest(test1);
//delegateTest=test1;
//delegateTest+=test1;
delegateTest+=test2;
delegateTest(a);
}
}
}
  2.C#中委托的发展
  上述是一个简单的委托例子,这里不再赘述具体的实现。基本来看委托和一个类的声明实现类似,首先以delegate关键字声明一个委托类型(这里注意声明的返回类型以及类型参数需要和后面对应的方法相同);然后声明和实例化一个委托类型变量,后调用该委托即可,注意添加到委托上的每个方法都会被调用,而我们并不关心这些方法是如何实现的。
  在C#2.0之前,委托的定义都是通过上述步骤实现的,而在C#2.0中,引入了匿名方法的概念,其实是简化了委托的写法。比如我们之前需要写:
  delegateTest=newMyDelegateTest(test1);
  现在可以简化为:
  delegateTest=delegate(intx){returnx*x;}
  而在C#3.0中,又引入了函数式语言中的lambda表达式进一步简化:
  delegateTest=x=>{returnx*x;}或直接x=>x*x;
  在C#4.0又有了泛型委托,其实是定义的时候加个泛型限制:
  delegateTMyDelegateTest<T>(Tx);
  3.通过委托实现观察者模式
  观察者模式是设计模式中一个很常见的模式,从生活中的例子来说,是对发布者进行关注的订阅者,在订阅者有更新时,会把消息推送给那些订阅者。在C#中可以用委托来实现观察者模式:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Text;
namespaceObserverModel
{
classProgram
{
//------------------------------------------------------------------
//委托充当订阅者类
publicdelegatevoidDelegateSender(objectsender);
//------------------------------------------------------------------
//发布者类
publicclassPublisher
{
publicDelegateSenderSenderEvent;
publicstringInfo;
//--------------------------------------------------------------------
publicPublisher(stringinfo)
{
this.Info=info;
}
//-----------------------------------------------------------------------
//添加和删除订阅者
publicvoidAddObserver(DelegateSenderob)
{
SenderEvent+=ob;
}
publicvoidRemoveObserver(DelegateSenderob)
{
SenderEvent-=ob;
}
//----------------------------------------------------------------------
//发布者更新
publicvoidUpdate()
{
if(SenderEvent!=null)
{
SenderEvent(this);
}
}
}
//--------------------------------------------------------------------------
//具体订阅者类1
publicclassSubscriber
{
publicstringName;
publicSubscriber(stringname)
{
this.Name=name;
}
publicvoidDoSomething(Objectsender=null)
{
Console.WriteLine("订阅者1的操作");
}
}
//--------------------------------------------------------------------------
//具体订阅者类2
publicclassSubscriber2
{
publicstringName;
publicSubscriber2(stringname)
{
this.Name=name;
}
publicvoidDoSomething2(Objectsender=null)
{
Console.WriteLine("订阅者2的操作");
}
}
staticvoidMain(string[]args)
{
Publisherpublisher=newPublisher("发布者");
Subscribersub1=newSubscriber("订阅者1");
Subscriber2sub2=newSubscriber("订阅者2");
//添加订阅者
publisher.AddObserver(newDelegateSender(sub1.DoSomething));
publisher.AddObserver(newDelegateSender(sub2.DoSomething));
publisher.Update();
//移除订阅者
publisher.RemoveObserver(newDelegateSender(sub1.DoSomething));
publisher.Update();
Console.ReadLine();
}
}
}