委托和事件都可以用来调用跟自己方法签名一样的方法,两者在使用中主要有以下区别:
- 委托和事件没有可比性,因为委托是类型,事件是对象;
- 委托可以在声明它的类外部进行调用,而事件只能在类的内部进行调用;
- 委托可以把一个方法作为参数代入另一个方法。 委托可以理解为指向一个函数的指针;
- 事件是委托的一个修饰符,加了event(事件)修饰之后,委托就被阉割了,假设这个加了修饰符的事件称为事件1,通过事件1我们可以更好地控制注册和注销,也就是对于一个外部类,那么他只能“注册自己+=、注销自己-=”。另外,外界也不能主动地触发一个事件。事件只能add、remove自己,不能赋值。也就是说事件只能+=、-=,不能= 。
以下是代码示例,加深对委托和事件的理解。
namespace xxxx
{
//发布事件的类
public class TestEventSource
{
//定义事件参数类
public class TestEventArgs : EventArgs
{
public readonly char KeyToRaiseEvent;
public TestEventArgs(char keyToRaiseEvent)
{
KeyToRaiseEvent = keyToRaiseEvent;
}
}
//定义delegate
public delegate void TestEventHandler(object sender, TestEventArgs e);
//用event 关键字声明事件对象
public event TestEventHandler TestEvent;
//关键字 //委托类型 //事件名
//事件触发方法
protected virtual void OnTestEvent(TestEventArgs e)
{
if (TestEvent != null)
TestEvent(this, e);
}
//引发事件
public void RaiseEvent(char keyToRaiseEvent)
{
TestEventArgs e = new TestEventArgs(keyToRaiseEvent);
OnTestEvent(e);
}
}
//监听事件的类
public class TestEventListener
{
//定义处理事件的方法,他与声明事件的delegate具有相同的参数和返回值类型
public void KeyPressed(object sender, TestEventSource.TestEventArgs e)
{
Console.WriteLine("发送者:{0},所按得健为:{1}", sender, e.KeyToRaiseEvent);
}
//订阅事件
public void Subscribe(TestEventSource evenSource)
{
evenSource.TestEvent += new TestEventSource.TestEventHandler(KeyPressed);
}
//取消订阅事件
public void UnSubscribe(TestEventSource evenSource)
{
evenSource.TestEvent -= new TestEventSource.TestEventHandler(KeyPressed);
}
}
//测试类
public class Test
{
public static void Main()
{
//创建事件源对象
TestEventSource es = new TestEventSource();
//创建监听对象
TestEventListener el = new TestEventListener();
//订阅事件
Console.WriteLine("订阅事件\n");
el.Subscribe(es);
//引发事件
Console.WriteLine("输入一个字符,再按enter键");
string s = Console.ReadLine();
es.RaiseEvent(s.ToCharArray()[0]);
//取消订阅事件
Console.WriteLine("\n取消订阅事件\n");
el.UnSubscribe(es);
//引发事件
Console.WriteLine("输入一个字符,再按enter健");
s = Console.ReadLine();
es.RaiseEvent(s.ToCharArray()[0]);
}
}
}