在真实的项目中,有的对象有相当多的事件,例如一个窗体就有好多种事件。默认情况下,当声明事件时,编译器将内存分配给一个事件字段,一存储事件信息。如果类中有好多事件未使用,则他们会不必要的占用内存。
这种情况下,.NETFramework提供了EventHandlerList类来减少内存的占用。它可以被看作事件的集合,只有需要响应的事件才拥有方法调用列表,才会在EventHandlerList对象中出现。
如果用EventHandlerList对象来保存事件的相应方法,必须为每一个事件编写特殊的访问器:
public delegate void OneDelegate(int value);
public class A
{
public EventHandlerList events = new EventHandlerList();
public event OneDelegate One
{
add { events.AddHandler("One",value); }
remove { events.RemoveHandler("One",value); }
}
}
这样事件就不像原先的字段,而是变成了类中的属性,而“add”“remove”就相当于“get”“set”。
激发事件时,原先的“标准”编写方法是:
事件(参数);
但是对于定义了事件访问器的事件,则必须按以下格式激发事件:
(EventHandlerList对象名[事件名] as定义事件的委托类型)(参数);
例如:
(events["One"] as OneDelegate)(100);
完整示例:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace UseEventListExample
{
public delegate void OneDelegate(int value);
public delegate void TwoDelegate(String str);
public class A
{
private EventHandlerList events = new EventHandlerList();
public event OneDelegate Event1
{
add
{
events.AddHandler("Event1", value);
}
remove
{
events.RemoveHandler("Event1", value);
}
}
public event TwoDelegate Event2
{
add
{
events.AddHandler("Event2", value);
}
remove
{
events.RemoveHandler("Event2", value);
}
}
public void FireTwoEvents()
{
//对于事件访问器,不能直接这样激发事件
//Event1(100);
//Event2("100");
(events["Event1"] as OneDelegate)(100);
(events["Event2"] as TwoDelegate)("100");
}
}
public class B
{
public void f1(int i)
{
Console.WriteLine("B.f1(int)");
}
public void f2(String str)
{
Console.WriteLine("B.f2(String)");
}
}
class Program
{
static void Main(string[] args)
{
B b = new B();
A a = new A();
a.Event1 += b.f1;
a.Event2 += b.f2;
a.FireTwoEvents();
Console.ReadKey();
}
}
}