随笔- 302
文章- 0
评论- 895
阅读-
78万
using System;
using System.Security.Permissions;
using System.Runtime.InteropServices;


namespace System.ComponentModel
{

/**//// <summary>
/// 组件类
/// </summary>
[DesignerCategory("Component"), ClassInterface(ClassInterfaceType.AutoDispatch), ComVisible(true)]

public class Component : MarshalByRefObject, IComponent, IDisposable
{


static Component()
{
//用于定位Disposed事件的关键字,不懂,为什么不用一个常量呢?
Component.EventDisposed = new object();
}


/**//// <summary>
/// 释放资源
/// </summary>

public void Dispose()
{
//调用重载的释放方法
this.Dispose(true);
GC.SuppressFinalize(this);
}


/**//// <summary>
/// 是否资源
/// </summary>
/// <param name="disposing">是否是主动释放资源</param>

protected virtual void Dispose(bool disposing)
{

if (disposing)
{
//防止并发还是重要的。

lock (this)
{
//如果我还在别人的容器里,要从容器中移动走。
//在容器代码中,调用这个代码前,已经将Site属性设置为Null了。

if ((this.site != null) && (this.site.Container != null))
{
this.site.Container.Remove(this);
}

//检查是否包含Disposed事件的拦截

if (this.events != null)
{
//注意,所有的事件都是放在这个Events中的,Disposed也是这样。
EventHandler disposedHandler = (EventHandler)this.events[Component.EventDisposed];

if (disposedHandler == null)
{
return;
}
disposedHandler(this, EventArgs.Empty);
}
}
}
}


/**//// <summary>
/// 垃圾收集器调用
/// </summary>

~Component()
{
this.Dispose(false);
}


/**//// <summary>
/// 获取服务
/// </summary>
/// <param name="service">要获取的服务类型</param>
/// <returns>服务的实例</returns>

protected virtual object GetService(Type service)
{
ISite site = this.site;

if (site != null)
{
//服务的获取顺序是:Component -> Site -> Container
return site.GetService(service);
}
return null;
}


/**//// <summary>
/// 重载了对象的文本显示
/// </summary>
/// <returns>新的文本</returns>

public override string ToString()
{
//如果存在站点,名称像这样的: btnOk[System.Windows.Froms.Button]
ISite site = this.site;

if (site != null)
{
return (site.Name + " [" + base.GetType().FullName + "]");
}
return base.GetType().FullName;
}


/**//// <summary>
/// 返回是否允许释放事件
/// </summary>
/// <remarks>
/// 如果继承类也将EventHandler添加到Events中的话(参见Disposed的实现)
/// 就可以通过重载此属性,来屏蔽所有事件的触发
/// </remarks>

protected virtual bool CanRaiseEvents
{

get
{
return true;
}
}


/**//// <summary>
/// 这个属性是被EventHandlerList访问的。实际上就是CanRaiseEvents属性
/// </summary>

internal bool CanRaiseEventsInternal
{

get
{
return this.CanRaiseEvents;
}
}


/**//// <summary>
/// 返回组件所在的容器
/// </summary>
/// <remarks>
/// IComponent接口并没有定义这个属性,这里只是为了使用方便而已
/// 容器是通过站点对象获取的。
/// </remarks>
[DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden), Browsable(false)]

public IContainer Container
{

get
{
ISite site = this.site;

if (site != null)
{
return site.Container;
}
return null;
}
}


/**//// <summary>
/// 返回是否是设计模式
/// </summary>
/// <remarks>
/// 和Container一样,为了方便使用添加的,实际数据的获取是通过站点获得的。
/// </remarks>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

protected bool DesignMode
{

get
{
ISite site = this.site;

if (site != null)
{
return site.DesignMode;
}
return false;
}
}


/**//// <summary>
/// 所有事件的存储地
/// </summary>
/// <remarks>
/// 通过自定义的EventHandlerList对象,Component实现了事件的统一管理,
/// 可以屏蔽所有的事件触发(通过CanRaiseEventsInternal)
/// </remarks>

protected EventHandlerList Events
{

get
{

if (this.events == null)
{
this.events = new EventHandlerList(this);
}
return this.events;
}
}


/**//// <summary>
/// 返回/设置组件的站点对象
/// </summary>
/// <remarks>
/// Component的核心思想就是这里了,可是他很简单,就是注射Site,
/// 就是注射了环境。
/// </remarks>
[Browsable(false), DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]

public virtual ISite Site
{

get
{
return this.site;
}

set
{
this.site = value;
}
}


/**//// <summary>
/// 对象的释放事件
/// </summary>
/// <remarks>
/// 通过拦截此事件,可以在拦截组件的释放。例如:
/// 当前选择了一些组件,但如果组件被释放,选择的组件将减少。
/// </remarks>
[Browsable(false), EditorBrowsable(EditorBrowsableState.Advanced)]

public event EventHandler Disposed
{

add
{
this.Events.AddHandler(Component.EventDisposed, value);
}

remove
{
this.Events.RemoveHandler(Component.EventDisposed, value);
}
}

// Fields
private static readonly object EventDisposed;
private EventHandlerList events;
private ISite site;
}


/**//// <summary>
/// Component专用的事件链表
/// </summary>
[HostProtection(SecurityAction.LinkDemand, SharedState = true)]

public sealed class EventHandlerList : IDisposable
{


/**//// <summary>
/// 初始化对象,允许不传递parent
/// </summary>

public EventHandlerList()
{
}


/**//// <summary>
/// 传递Component的父对象初始化实例
/// </summary>
/// <param name="parent">所在的组件</param>

internal EventHandlerList(Component parent)
{
this.parent = parent;
}


/**//// <summary>
/// 添加Handler
/// </summary>
/// <param name="key">事件的查询关键字</param>
/// <param name="value">新的Handler</param>

public void AddHandler(object key, Delegate value)
{
//在链表中寻找这个事件
EventHandlerList.ListEntry entry = this.Find(key);

if (entry != null)
{
//如果找到了,就合并成新的Handler,
entry.handler = Delegate.Combine(entry.handler, value);
}

else
{
//如果没有找到,为链表添加新的头。
this.head = new EventHandlerList.ListEntry(key, value, this.head);
}
}


/**//// <summary>
/// 添加一批新的Handlers
/// </summary>
/// <param name="listToAddFrom">列表</param>

public void AddHandlers(EventHandlerList listToAddFrom)
{
//循环链表,一个个加

for (EventHandlerList.ListEntry entry = listToAddFrom.head; entry != null; entry = entry.next)
{
this.AddHandler(entry.key, entry.handler);
}
}


/**//// <summary>
/// 释放资源
/// </summary>

public void Dispose()
{
this.head = null;
}


/**//// <summary>
/// 寻找某个关键字的事件
/// </summary>
/// <param name="key">要寻找的事件的关键字</param>
/// <returns>如果找到就返回他的结构,否则返回Null</returns>

private EventHandlerList.ListEntry Find(object key)
{
//这里使用了while循环找,上面那个AddHandlers是用For。
EventHandlerList.ListEntry entry = this.head;

while (entry != null)
{

if (entry.key == key)
{
break;
}
entry = entry.next;
}
return entry;
}


/**//// <summary>
/// 在链表中移除某个Handler
/// </summary>
/// <param name="key">事件关键字</param>
/// <param name="value">要移除的Handler</param>

public void RemoveHandler(object key, Delegate value)
{
//在链表中寻找,如果找到就Remove掉
EventHandlerList.ListEntry entry = this.Find(key);

if (entry != null)
{
entry.handler = Delegate.Remove(entry.handler, value);
}
}


/**//// <summary>
/// 获取某个事件的Handler
/// </summary>
/// <param name="key">事件的关键字</param>
/// <returns>如果找到事件,且没有设置屏蔽,就返回他</returns>

public Delegate this[object key]
{

get
{
EventHandlerList.ListEntry entry = null;
//如果所在组件设置了不触发事件,将不会Find,返回Null

if ((this.parent == null) || this.parent.CanRaiseEventsInternal)
{
entry = this.Find(key);
}

if (entry != null)
{
return entry.handler;
}
return null;
}

set
{
//相当与AddHandler
EventHandlerList.ListEntry entry = this.Find(key);

if (entry1 != null)
{
entry1.handler = value;
}

else
{
this.head = new EventHandlerList.ListEntry(key, value, this.head);
}
}
}
// Fields
private ListEntry head;
private Component parent;

//存储所有Handler的结构

private sealed class ListEntry
{

/**//// <summary>
/// 构造新结构
/// </summary>
/// <param name="key">当前新事件类型的关键字</param>
/// <param name="handler">新委托</param>
/// <param name="next">下一个结构(链表)</param>

public ListEntry(object key, Delegate handler, EventHandlerList.ListEntry next)
{
this.next = next;
this.key = key;
this.handler = handler;
}
// Fields
internal Delegate handler;
internal object key;
internal EventHandlerList.ListEntry next;
}
}
}
posted on
2005-12-26 11:32
编写人生
阅读(
891)
评论()
编辑
收藏
举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 【设计模式】告别冗长if-else语句:使用策略模式优化代码结构