zoukankan      html  css  js  c++  java
  • 扩展功能的 CollectionBaseEx

    因为平时使用 System.Collections.CollectionBase 时候发现有些不足,故而作了一个扩展的 CollectionBaseEx,代码如下,因为注释较多,故不再解释。

        /// <summary>
        
    /// 增强的 CollectionBase ,支持排序,和更多的通知
        
    /// </summary>

        public class CollectionBaseEx : IList
        
    {
            
    private ArrayList m_InnerList;
            
    private bool m_Duplicated;        // 是否允许重复元素
            private bool m_Sorted;            // 是否允许排序
            private IComparer m_Comparer;    // 排序时候使用的比较器
            private bool m_SingleCheck;        // 是否在处理时候要处理单个元素,引发Include/Exclude事件

            
    /// <summary>
            
    /// 默认构造函数
            
    /// </summary>

            protected CollectionBaseEx()
            
    {
                m_InnerList 
    = new ArrayList();
                m_Duplicated 
    = true;
                m_Sorted 
    = false;
                m_Comparer 
    = System.Collections.Comparer.Default;
                m_SingleCheck 
    = false;
            }


            
    /// <summary>
            
    /// 构造函数
            
    /// </summary>
            
    /// <param name="duplicated">是否允许重复元素</param>
            
    /// <param name="singleCheck">是否对每一个元素进行检查并发出通知</param>
            
    /// <param name="sorted">对值进行排序</param>
            
    /// <param name="comparer">比较器</param>

            protected CollectionBaseEx(bool duplicated, bool singleCheck, bool sorted, IComparer comparer) : this()
            
    {
                m_Duplicated 
    = duplicated;
                m_Sorted 
    = sorted;
                m_Comparer 
    = comparer;
                m_SingleCheck 
    = singleCheck;
            }


            
    /// <summary>
            
    /// 操作接口,能够触发各种通知
            
    /// </summary>

            protected IList List get return this; } }

            
    /// <summary>
            
    /// 实际存放数据的容器
            
    /// </summary>

            protected ArrayList InnerList
            
    {
                
    get return m_InnerList; }
                
    set
                
    {
                    
    if (value == null)
                        
    throw new ArgumentNullException("value can not be null""value");
                    m_InnerList 
    = value;
                }

            }


            
    /// <summary>
            
    /// 允许重复元素
            
    /// </summary>

            protected bool Duplicated get return m_Duplicated; } set { m_Duplicated = value; } }

            
    /// <summary>
            
    /// 排序
            
    /// </summary>

            protected bool Sorted get return m_Sorted; } set { m_Sorted = value; } }

            
    /// <summary>
            
    /// 对每一个元素进行检查并发出通知
            
    /// </summary>

            protected bool SingleCheck get return m_SingleCheck; } set { m_SingleCheck = value; } }

            
    /// <summary>
            
    /// 比较器
            
    /// </summary>

            protected IComparer Comparer get return m_Comparer; } set { m_Comparer = value; } }


            
    #region callback

            
    /// <summary>
            
    /// 清除所有元素之前的通知
            
    /// </summary>

            protected virtual void OnClear(){}
            
    /// <summary>
            
    /// 所有元素清除成功之后的通知
            
    /// </summary>

            protected virtual void OnClearComplete(){}
            
    /// <summary>
            
    /// 插入元素之前的通知
            
    /// </summary>
            
    /// <param name="index">元素插入位置</param>
            
    /// <param name="value">插入的值</param>

            protected virtual void OnInsert(int index, object value){}
            
    /// <summary>
            
    /// 元素插入成功之后的通知
            
    /// </summary>
            
    /// <param name="index">元素插入位置</param>
            
    /// <param name="value">插入的值</param>

            protected virtual void OnInsertComplete(int index, object value){}
            
    /// <summary>
            
    /// 删除元素之前的通知
            
    /// </summary>
            
    /// <param name="index">要删除元素的位置</param>
            
    /// <param name="value">要删除的元素</param>

            protected virtual void OnRemove(int index, object value){}
            
    /// <summary>
            
    /// 删除元素之后的通知
            
    /// </summary>
            
    /// <param name="index">要删除元素的位置</param>
            
    /// <param name="value">要删除的元素</param>

            protected virtual void OnRemoveComplete(int index, object value){}
            
    /// <summary>
            
    /// 设置元素的值之前的通知
            
    /// </summary>
            
    /// <param name="index">元素的位置</param>
            
    /// <param name="oldValue">该位置的当前的值</param>
            
    /// <param name="newValue">将要存放到该位置的新值</param>
            
    /// <remarks>如果<see cref="Sorted"/>为真,则设置成功之后的元素会移动到正确的位置上去</remarks>

            protected virtual void OnSet(int index, object oldValue, object newValue){}
            
    /// <summary>
            
    /// 设置元素的值成功之后的通知
            
    /// </summary>
            
    /// <param name="index">元素位置</param>
            
    /// <param name="oldValue">该位置以前的值</param>
            
    /// <param name="newValue">该位置当前的值</param>
            
    /// <remarks>如果<see cref="Sorted"/>为真,则设置成功之后的元素会移动到正确的位置上去</remarks>

            protected virtual void OnSetComplete(int index, object oldValue, object newValue){}

            
    /// <summary>
            
    /// 通知对元素进行正确性检查
            
    /// </summary>
            
    /// <param name="value">将要存放的值</param>

            protected virtual void OnValidate(object value){}

            
    /// <summary>
            
    /// 将要把元素存放到容器之前的通知
            
    /// </summary>
            
    /// <param name="value">将要存放的值</param>

            protected virtual void OnInclude(object value){}

            
    /// <summary>
            
    /// 将要把元素从容器中脱离之前的通知
            
    /// </summary>
            
    /// <param name="value">将要脱离容器的值</param>

            protected virtual void OnExclude(object value){}

            
    #endregion


            
    #region internal logic

            
    private  void BeforeClear()
            
    {
                
    if( m_SingleCheck )
                
    {
                    
    int index = 0;
                    
    try
                    
    {
                        
    while( index < m_InnerList.Count)
                        
    {
                            OnExclude(m_InnerList[index]);
                            
    ++ index;
                        }

                    }

                    
    catch(Exception)
                    
    {
                        
    while--index >= 0 )
                            OnInclude(m_InnerList[index]);
                        
    throw;
                    }

                }


                OnClear();
            }


            
    private  void AfterClearComplete()
            
    {
                OnClearComplete();
            }


            
    private  void BeforeInsert(int index, object value)
            
    {
                
    if( m_Sorted )
                    
    throw new InvalidOperationException("排序状态下不能使用");
                
    ifthis.m_SingleCheck )
                    OnInclude(value);
                OnInsert(index, value);
            }


            
    private  void AfterInsertComplete(int index, object value)
            
    {
                OnInsertComplete(index, value);
            }


            
    private  void BeforeRemove(int index, object value)
            
    {
                
    if( m_SingleCheck )
                    OnExclude(value);
                OnRemove(index, value);
            }


            
    private  void AfterRemoveComplete(int index, object value)
            
    {
                OnRemoveComplete(index, value);
            }


            
    private  void BeforeSet(int index, object oldValue, object newValue)
            
    {
                
    if( m_SingleCheck )
                    OnInclude(newValue);
                OnSet(index, oldValue, newValue);
            }


            
    private  void AfterSetComplete(int index, object oldValue, object newValue)
            
    {
                
    if( m_SingleCheck )
                    OnExclude(oldValue);
                OnSetComplete(index, oldValue, newValue);
            }


            
    private  void CheckValidate(object value)
            
    {
                
    if (value == null)
                    
    throw new ArgumentNullException("value can not be null""value");
                
    if!Duplicated 
                    
    && (( !m_Sorted && m_InnerList.IndexOf(value) != -1 ) 
                        
    || (m_Sorted && m_InnerList.BinarySearch(value, m_Comparer) >= 0)
                    ))
                    
    throw new ArgumentException("object exists");

                OnValidate(value);
            }


            
    #endregion


            
    #region IList 成员

            
    bool IList.IsReadOnly get return m_InnerList.IsReadOnly; } }

            
    object IList.this[int index]
            
    {
                
    get return m_InnerList[index]; }
                
    set
                
    {
                    CheckValidate(value);
                    
    object old = m_InnerList[index];
                    
    this.BeforeSet(index, old, value);
                    m_InnerList[index] 
    = value;
                    
    try
                    
    {
                        
    this.AfterSetComplete(index, old, value);
                        
    if( m_Sorted )    // 移动到正确位置
                        {
                            m_InnerList.RemoveAt(index);
                            
    int pos = m_InnerList.BinarySearch(value, m_Comparer);
                            
    if( pos < 0 ) pos = ~pos;
                            m_InnerList.Insert(pos, value);
                        }

                    }

                    
    catch (Exception)
                    
    {
                        m_InnerList[index] 
    = old;
                        
    throw;
                    }

                }

            }


            
    public void RemoveAt(int index)
            
    {
                
    object obj = m_InnerList[index];

                
    this.BeforeRemove(index, obj);
                m_InnerList.RemoveAt(index);
                
    this.AfterRemoveComplete(index, obj);
            }


            
    void IList.Insert(int index, object value)
            
    {
                CheckValidate(value);
                
    this.BeforeInsert(index, value);
                m_InnerList.Insert(index, value);
                
    try
                
    {
                    
    this.AfterInsertComplete(index, value);
                }

                
    catch (Exception)
                
    {
                    m_InnerList.RemoveAt(index);
                    
    throw;
                }

            }


            
    void IList.Remove(object value)
            
    {
                
    int index = m_InnerList.IndexOf(value);
                
    if( index < 0 )
                    
    throw new ArgumentException("object not found");
                
    this.BeforeRemove(index, value);
                m_InnerList.Remove(value);
                
    this.AfterRemoveComplete(index, value);
            }


            
    bool IList.Contains(object value)
            
    {
                
    return m_InnerList.Contains(value);
            }


            
    public void Clear()
            
    {
                
    this.BeforeClear();
                m_InnerList.Clear();
                
    this.AfterClearComplete();
            }


            
    int IList.IndexOf(object value)
            
    {
                
    return m_InnerList.IndexOf(value);
            }


            
    int IList.Add(object value)
            
    {
                CheckValidate(value);
                
    int index = m_InnerList.Count;
                
    if( m_Sorted )
                
    {
                    index 
    = m_InnerList.BinarySearch(value, m_Comparer);
                    
    if( index < 0 )    index = ~index;
                }

                
    this.BeforeInsert(index, value);
                
    if!m_Sorted )
                    index 
    = m_InnerList.Add(value);
                
    else
                    m_InnerList.Insert(index, value);

                
    try
                
    {
                    
    this.AfterInsertComplete(index, value);
                }

                
    catch (Exception)
                
    {
                    m_InnerList.RemoveAt(index);
                    
    throw;
                }

                
    return index;
            }


            
    bool IList.IsFixedSize get return m_InnerList.IsFixedSize; } }

            
    #endregion


            
    #region ICollection 成员

            
    bool ICollection.IsSynchronized get return m_InnerList.IsSynchronized; } }

            
    public int Count get return m_InnerList.Count; } }

            
    void ICollection.CopyTo(Array array, int index)
            
    {
                m_InnerList.CopyTo(array, index);
            }


            
    object ICollection.SyncRoot get return m_InnerList.SyncRoot; } }


            
    #endregion


            
    #region IEnumerable 成员

            
    public IEnumerator GetEnumerator()
            
    {
                
    return m_InnerList.GetEnumerator();
            }


            
    #endregion


            
    public IEnumerator GetEnumerator(int index, int count)
            
    {
                
    return m_InnerList.GetEnumerator(index, count);
            }


        }

  • 相关阅读:
    MOSS工作流开发+ Email提醒
    使用VS.net開發MOSS工作流(請假單)
    配置单一登录
    使用VS.NET手動創建一個MOSS的BDC實體
    UDDI&wsdl
    telnet
    thoughtworks~
    GIS
    MySQL中修改root密码的方法[转]
    libconfig
  • 原文地址:https://www.cnblogs.com/BigTall/p/143496.html
Copyright © 2011-2022 走看看