看了前面一篇委托的用法中http://blog.csdn.net/yysyangyangyangshan/article/details/8252192,我们看到,

        public void Description(string programerName, DescriptionDelegate description)          {              description(programerName);          }

这个方法时传一个DescriptionDelegate description委托类型进来,那么对于这个方法再做一下修改,能用起来方便一些,代码也更合理一些。把委托封装起来,然后把不同语言的程序员描述方法提出来:
封装:

    public class ProgramDescriptionDelegate2      {          public delegate void DescriptionDelegate(string programerName);            public DescriptionDelegate myDelegate;            public void Description(string programerName)          {              myDelegate(programerName);          }      }

提出的类:

    public class TestDescriptionDelegate2      {          public void CsharpProgramer(string programerName)          {              Console.WriteLine(string.Format("{0} 使用C#编程!", programerName));          }            public void CProgramer(string programerName)          {              Console.WriteLine(string.Format("{0}使用C语言编程!", programerName));          }            public void JavaProgramer(string programerName)          {              Console.WriteLine(string.Format("{0} 使用Java语言编程!", programerName));          }            public void Test()          {              ProgramDescriptionDelegate2 pe = new ProgramDescriptionDelegate2();                pe.myDelegate = CsharpProgramer;                pe.myDelegate += CProgramer;                pe.Description("SamYang");          }      }

这样就比较合理一些,因为public void CsharpProgramer(string programerName)这些方法,应该是用户可以随时定义的,可以看做随时变动的。而ProgramDescriptionDelegate2完全作为一个公共的类,它只负责执行绑定在委托上的方法。
调用:

            TestDescriptionDelegate2 t = new TestDescriptionDelegate2();                t.Test();

输出:

再回过来看ProgramDescriptionDelegate2类,public DescriptionDelegate myDelegate;应该是一个字段,根据面向对象的封装性,字段要封装为属性。那么在这里封装我们要使用一个很有用的字段event。
封装如下:

   public class ProgramerDescriptionEvent      {          public delegate void DescriptionDelegate(string programerName);            private event DescriptionDelegate myEvent;            public event DescriptionDelegate MyEvent          {              add { this.myEvent += value; }                remove { this.myEvent -= value; }          }            public void Description(string programerName)          {              myEvent(programerName);          }      }

 

  public class TestEvent      {          public void CsharpProgramer(string programerName)          {              Console.WriteLine(string.Format("{0} 使用C#编程!", programerName));          }            public void CProgramer(string programerName)          {              Console.WriteLine(string.Format("{0}使用C语言编程!", programerName));          }            public void JavaProgramer(string programerName)          {              Console.WriteLine(string.Format("{0} 使用Java语言编程!", programerName));          }            public void Test()          {              ProgramerDescriptionEvent pe = new ProgramerDescriptionEvent();                pe.MyEvent += CsharpProgramer;                pe.MyEvent += JavaProgramer;                pe.Description("SamYang");//一般这个执行是放在引起事件执行的地方          }      }

调用:

            TestEvent te = new TestEvent();                te.Test();

结果如下:

可以看出,什么是事件,其实本质使用的是委托,但是使用了event是这种委托变成了一种机制,叫事件。
那么看msdn对委托和事件的描述:
事件是对象发消息,以发信号通知操作的发生,操作可能是由用户交互(鼠标、键盘操作等)引起的,或者由某些其他的程序逻辑触发。捕获事件并对其作出响应的对象叫做事件接收方。
在事件通信中,事件发送方类不知道哪个对象或方法将接收到它引发的事件。所需要的是在源和接收方之间存在一个媒介。.NET Framework 定义了一个特殊的类型 (Delegate),该类型提供函数指针的功能。委托是可保存对方法的引用的类。与其他的类不同,委托类具有一个签名,并且它只能对与其签名匹配的方法进行引用。这样,委托就等效于一个类型安全函数指针或一个回调。虽然委托具有许多其他的用途,但这里只讨论委托的事件处理功能。一个委托声明足以定义一个委托类。声明提供委托的签名,公共语言运行库提供实现。例如:
public delegate void AlarmEventHandler(object sender, AlarmEventArgs e);
delegate 关键字通知编译器 AlarmEventHandler 是一个委托类型。按照约定,.NET Framework 中的事件委托有两个参数:引发事件的源和该事件的数据。即sender和e。

代码下载:http://download.csdn.net/detail/yysyangyangyangshan/4844716