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;
}
}
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧