C#事件の事件访问器
在真实的项目中,有的对象有相当多的事件,例如一个窗体就有好多种事件。默认情况下,当声明事件时,编译器将内存分配给一个事件字段,一存储事件信息。如果类中有好多事件未使用,则他们会不必要的占用内存。
这种情况下,.NETFramework提供了EventHandlerList类来减少内存的占用。它可以被看作事件的集合,只有需要响应的事件才拥有方法调用列表,才会在EventHandlerList对象中出现。
EventHandlerList:
为了节省内存而设计的。
当你定义一个事件的时候,通常也要定义相应的委托,在初始化的时候,就会为所有事件、委托分配内存空间。
但如果有许多未被使用到的事件,那么这些空间就浪费了。
EventHandlerList是专门用于保存委托的线性表,它存储的是Delegate类型,所有委托的基类,也就是任意委托都可存储。
可以看到无论是Form,还是HttpAppliaction类,都有定义一个EventHandlerList类型的Events属性,用于存储所有事件委托
如果用EventHandlerList对象来保存事件的相应方法,必须为每一个事件编写特殊的访问器:
class
MyControl1
{
// 即使没有订阅,每个事件作为类成员需要4个字节(的引用,没有订阅时为null)。
// Winform的控件至少有70个事件, 这就要280个字节,且大部分事件都没有被用到。
// 就是说每个UI上的控件,Lable,Button,TextBox,等等,每个都可能浪费约300个字节。
public
event
EventHandler Initializing;
public
event
EventHandler Initialized;
// ...
public
event
EventHandler MouseDown;
public
event
EventHandler MouseUp;
public
event
EventHandler MouseMove;
public
event
EventHandler MouseClick;
public
event
EventHandler MouseDoubleClick;
public
event
EventHandler KeyDown;
public
event
EventHandler KeyUp;
// ...
}
class
MyControl2
{
// 一个EventHandlerList初始只要4个字节(的引用)
private
EventHandlerList _events;
protected
EventHandlerList Events
{
get
{
if
(_events ==
null
) _events =
new
EventHandlerList();
return
_events;
}
}
public
event
EventHandler Initializing
{
add { Events.AddHandler(
"Initializing"
, value); }
// 按需增加
remove { Events.RemoveHandler(
"Initializing"
, value); }
}
public
event
EventHandler Initialized
{
add { Events.AddHandler(
"Initialized"
, value); }
remove { Events.RemoveHandler(
"Initialized"
, value); }
}
}
{ // Create an event for each interface event
event EventHandler PreDrawEvent;
event EventHandler PostDrawEvent;
object objectLock = new Object();
event EventHandler IDrawingObject.OnDraw
{
add
{ lock (objectLock)
{
PreDrawEvent += value;
}
}
remove
{
lock (objectLock)
{
PreDrawEvent -= value;
}
}
}