zoukankan      html  css  js  c++  java
  • 反编译 Component重要类,全文解释 - 容器篇

    using System;
    using System.Security.Permissions;

    namespace System.ComponentModel {

        
    /// <summary>
        
    /// 容器类
        
    /// </summary>

        [HostProtection(SecurityAction.LinkDemand, SharedState = true)]
        
    public class Container : IContainer, IDisposable {
            
    /// <summary>
            
    /// 初始化对象
            
    /// </summary>

            public Container() {
                
    //用于锁定的锁定资源
                this.syncObj = new object();
            }


            
    /// <summary>
            
    /// 向容器添加新的组件
            
    /// </summary>
            
    /// <param name="component">新加入的组件</param>

            public virtual void Add(IComponent component) {
                
    //Name为null处理
                this.Add(component, null);
            }


            
    /// <summary>
            
    /// 向容器添加新的组件并指定名称
            
    /// </summary>
            
    /// <param name="component">新添加的组件</param>
            
    /// <param name="name">组件的名称</param>

            public virtual void Add(IComponent component, string name) {
                
    //防止并发添加
                lock (this.syncObj) {
                    
    //允许component参数为null,并不出错,而是忽略
                    if (component == null{
                        
    return;
                    }


                    ISite oldSite 
    = component.Site;
                    
    //如果新加入的组件包含了站点对象,且站点指向的就是自己,就不继续添加了;
                    
    //说白了,就是不允许重复加入容器
                    if ((oldSite != null&& (oldSite.Container == this)) {
                        
    return;
                    }


                    
    //如果没有初始化过站点数组,就初始化4个
                    if (this.sites == null{
                        
    this.sites = new ISite[4];
                    }

                    
    else {
                        
    //??难度第一次就用校验名称了吗?
                        this.ValidateName(component, name);

                        
    //站点对象是存放在数组中的,所以当空间不足时,需要手工增大。
                        if (this.sites.Length == this.siteCount) {
                            
    //新的大小是原大小的2倍。
                            ISite[] newSites = new ISite[this.siteCount * 2];
                            
    //将原始数据复制到新的数组
                            Array.Copy(this.sites, 0, newSites, 0this.siteCount);
                            
    this.sites = newSites;
                        }

                    }


                    
    //如果新加入的组件,原先有一个容器了,就应该从原容器中移除。不能有俩个老爸吧。
                    if (oldSite != null{
                        oldSite.Container.Remove(component);
                    }


                    
    //创建新的站点对象,这个CreateSite是可以重载的。
                    ISite newSite = this.CreateSite(component, name);
                    
    //增加站点计数器,并将新站点放在容器的最后。
                    this.sites[this.siteCount++= newSite;
                    
    //为组件注射新的站点对象。
                    component.Site = newSite;
                    
    //注意这里:他将components设置为null,以便Components属性重构数组的内容,
                    
    //当现在就没有必要马上重构,优化
                    this.components = null;
                }

            }


            
    /// <summary>
            
    /// 为新组件创建站点对象
            
    /// </summary>
            
    /// <param name="component">要创建站点的组件对象</param>
            
    /// <param name="name">组件预定的名称</param>
            
    /// <returns>新的站点对象</returns>

            protected virtual ISite CreateSite(IComponent component, string name) {
                
    return new Container.Site(component, this, name);
            }


            
    /// <summary>
            
    /// 释放当前容器对象
            
    /// </summary>

            public void Dispose() {
                
    //这个方法是不能重载的,但是他会调用下面的方法,而这个方法是可重载的。
                this.Dispose(true);
                
    //回收我吧。
                GC.SuppressFinalize(this);
            }


            
    /// <summary>
            
    /// 重载此方法来释放自定义的资源
            
    /// </summary>
            
    /// <param name="disposing">true表示调用方主动提出释放,false表示是垃圾回收器在调用此方法。</param>

            protected virtual void Dispose(bool disposing) {
                
    //只有主动要求释放的时候才会做这些事情。
                if (disposing) {
                    
    //锁定一下,并发小心啊。
                    lock (this.syncObj) {
                        
    int i;
                        
    //循环所有的子组件,将他们一一释放,也就是说,
                        
    //我不能活,我的孩子们也要死。好残忍哦。
                        while (this.siteCount > 0{
                            
    //怎么喜欢联等号,看着不舒服,这个释放过程是从后向前释放的。
                            this.siteCount = i = this.siteCount - 1;
                            ISite site 
    = this.sites[i];
                            
    //取消组件的站点引用,然后释放他。
                            site.Component.Site = null;
                            site.Component.Dispose();
                        }

                        
    //取消所有站点的引用,也就是取消了对所有子组件的引用。
                        
    //虽然站点持有了容器的引用,但是现在容器不持有站点了,
                        
    //也就取消了循环引用。
                        this.sites = null;
                        
    this.components = null;
                    }

                }

            }


            
    /// <summary>
            
    /// 当容器被垃圾回收器回收前调用
            
    /// </summary>

            ~Container() {
                
    //一般的,这个调用基本上没有什么事情可做。
                this.Dispose(false);
            }


            
    /// <summary>
            
    /// 获取服务
            
    /// </summary>
            
    /// <param name="service">要获取的服务类型</param>
            
    /// <returns>如果找到此服务就返回服务的实例,否则返回null</returns>

            protected virtual object GetService(Type service) {
                
    //在默认的Component实现中,他的GetService最终就是调用这个容器的GetService
                
    //所以,要为组件提供其他的服务,可以重载此方法已提供更多的服务
                if (service != typeof(IContainer)) {
                    
    return null;
                }

                
    return this;
            }


            
    /// <summary>
            
    /// 从容器中移除指定的组件
            
    /// </summary>
            
    /// <param name="component">要移除的组件对象</param>

            public virtual void Remove(IComponent component) {
                
    this.Remove(component, false);
            }


            
    //这个是实际的移除方法
            private void Remove(IComponent component, bool preserveSite) {
                
    //还是小心并发
                lock (this.syncObj) {
                    
    //允许参数为null,不出错,退出。
                    if (component == null{
                        
    return;
                    }


                    
    //获取要移除的组件站点对象
                    ISite oldSite = component.Site;
                    
    //没有站点对象,不关我的事情,退出
                    if (oldSite == null{
                        
    return;
                    }

                    
    //不是我容器下的东西,也不关我的事情,退出
                    if (oldSite.Container != this{
                        
    return;
                    }


                    
    //首先组件的站点对象,不再指向他。
                    if (!preserveSite) {
                        component.Site 
    = null;
                    }


                    
    //找到他,移除的时候比较简单,并不调用他的Dispose方法,奇怪。
                    for (int i = 0; i < this.siteCount; i++{
                        
    if (this.sites[i] == oldSite) {
                            
    //减少计数器
                            this.siteCount--;
                            
    //将删除的位置之后的数据向前移动一个。
                            Array.Copy(this.sites, (int)(i + 1), this.sites, i, (int)(this.siteCount - i));
                            
    //将最后一个站点设置为空
                            this.sites[this.siteCount] = null;
                            
    //内容发生变化,设置components为null,以便重新构建
                            this.components = null;
                            
    return;
                        }

                    }

                }

            }


            
    /// <summary>
            
    /// 移除组件,但不删除组件的站点属性。
            
    /// </summary>
            
    /// <param name="component">要移除的组件</param>

            protected void RemoveWithoutUnsiting(IComponent component) {
                
    //这是一个特殊的方法,不知用在什么地方。
                this.Remove(component, true);
            }


            
    /// <summary>
            
    /// 校验新加入的组件的名称正确性
            
    /// </summary>
            
    /// <param name="component">要校验的组件</param>
            
    /// <param name="name">组件的名称</param>

            protected virtual void ValidateName(IComponent component, string name) {
                
    //参数校验
                if (component == null{
                    
    throw new ArgumentNullException("component");
                }


                
    //没有名字,不算有问题
                if (name != null{
                    
    //循环所有的站点。但不明白的是为什么要取站点的最小值和数组的最小值,难道siteCount不是总是小于sites.Length的吗?
                    for (int i = 0; i < Math.Min(this.siteCount, this.sites.Length); i++{
                        ISite site 
    = this.sites[i];
                        
    //如果 站点有效 且
                        
    //     站点有名字 且
                        
    //     站点的名字和新名字相等 且
                        
    //     站点对应的组件不是检查的组件(自己)。
                        if (((site != null&& (site.Name != null)) &&                         
                            (
    string.Equals(site.Name, name, StringComparison.OrdinalIgnoreCase) && (site.Component != component))) {
                            
    //该组件会被继承并且是只读的,就不报错,Why?
                            InheritanceAttribute attribute1 = (InheritanceAttribute)TypeDescriptor.GetAttributes(site.Component)[typeof(InheritanceAttribute)];
                            
    if (attribute1.InheritanceLevel != InheritanceLevel.InheritedReadOnly) {
                                
    throw new ArgumentException("名字重复了", name);
                            }

                        }

                    }

                }

            }


            
    /// <summary>
            
    /// 获取容器的所有组件
            
    /// </summary>

            public virtual ComponentCollection Components {
                
    get {
                    
    //组件集合是动态创建的。
                    ComponentCollection retCollection;
                    
    lock (this.syncObj) {
                        
    if (this.components == null{
                            
    //创建一个数组,将所有的站点的组件对象收集起来
                            IComponent[] newComponents = new IComponent[this.siteCount];
                            
    for (int i = 0; i < this.siteCount; i++{
                                newComponents[i] 
    = this.sites[i].Component;
                            }

                            
    //这个赋值好像早了点,因为如果过滤服务失败,下次方法Components时就时错误的结果了,
                            
    //因为comonents已经不是null了。
                            this.components = new ComponentCollection(newComponents);
                            
    //初始化状态checkedFilter为false,所以即使下面的条件不通过,也还是会去申请的。
                            
    //如果申请过了,但是上次没有申请到,就重新申请。
                            
    //只要有一次成功申请到,就不会再申请了。
                            if ((this.filter == null&& this.checkedFilter) {
                                
    this.checkedFilter = false;
                            }

                        }

                        
    //如果没有申请过过滤服务,就申请一次。
                        if (!this.checkedFilter) {
                            
    //缓存过滤服务,总觉得缓存危险
                            this.filter = this.GetService(typeof(ContainerFilterService)) as ContainerFilterService;
                            
    this.checkedFilter = true;
                        }

                        
    //过滤服务有效
                        if (this.filter != null{
                            
    //过滤数据,过滤有结果,才放入新结果
                            ComponentCollection newCollection = this.filter.FilterComponents(this.components);
                            
    if (newCollection != null{
                                
    this.components = newCollection;
                            }

                        }

                        retCollection 
    = this.components;
                    }

                    
    return retCollection;
                }

            }


            
    // Fields
            private bool checkedFilter;                     //申请过过滤服务吗
            private ComponentCollection components;         //缓存的组件集合
            private ContainerFilterService filter;          //缓存的过滤服务
            private int siteCount;                          //当前站点总数
            private ISite[] sites;                          //当前所有的站点存放处(可能有空地)
            private object syncObj;                         //锁定对象

            
    /// <summary>
            
    /// 内置的站点对象,不需要公开的.
            
    /// </summary>

            private class Site : ISite, IServiceProvider {
                
    /// <summary>
                
    /// 初始化站点
                
    /// </summary>
                
    /// <param name="component">站点对应的组件</param>
                
    /// <param name="container">所在容器</param>
                
    /// <param name="name">新的名称</param>

                internal Site(IComponent component, Container container, string name) {
                    
    this.component = component;
                    
    this.container = container;
                    
    this.name = name;
                }


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

                public object GetService(Type service) {
                    
    //如果申请的是ISite,就是自己了.
                    if (service != typeof(ISite)) {
                        
    //实际调用的是容器的GetService
                        
    //Component的GetService调用顺序是:
                        
    // Component.GetService -> Site.GetService -> Container.GetService
                        return this.container.GetService(service);
                    }

                    
    return this;
                }

     

                
    /// <summary>
                
    /// 返回站点关联的组件
                
    /// </summary>

                public IComponent Component {
                    
    get {
                        
    return this.component;
                    }

                }


                
    /// <summary>
                
    /// 返回站点所在的容器
                
    /// </summary>

                public IContainer Container {
                    
    get {
                        
    return this.container;
                    }

                }


                
    /// <summary>
                
    /// 返回是否是设计模式
                
    /// </summary>

                public bool DesignMode {
                    
    get {
                        
    //总是返回false,真的不知道为什么设计成一个属性,而不是GetService(IDesignService)的方式。郁闷
                        return false;
                    }

                }


                
    /// <summary>
                
    /// 返回/设置站点的名称
                
    /// </summary>

                public string Name {
                    
    get {
                        
    return this.name;
                    }

                    
    set {
                        
    //校验名称,名字只会存储在这里。
                        if (((value == null|| (this.name == null)) || !value.Equals(this.name)) {
                            
    this.container.ValidateName(this.component, value);
                            
    this.name = value;
                        }

                    }

                }

     
                
    private IComponent component;
                
    private Container container;
                
    private string name;
            }

        }

    }

  • 相关阅读:
    cf B. Sereja and Suffixes
    cf E. Dima and Magic Guitar
    cf D. Dima and Trap Graph
    cf C. Dima and Salad
    最短路径问题(floyd)
    Drainage Ditches(网络流(EK算法))
    图结构练习—BFSDFS—判断可达性(BFS)
    Sorting It All Out(拓扑排序)
    Power Network(最大流(EK算法))
    Labeling Balls(拓扑)
  • 原文地址:https://www.cnblogs.com/tansm/p/303525.html
Copyright © 2011-2022 走看看