集合代理类的实现

【问题的提出】

以Windows系统的文件系统为例,文件系统对象目录(DirectoryInfo)或者文件(FileInfo)都派生自文件系统对象(FileSystemInfo),但在我们实际应用中,可能需要这样:

一个集合IList<FileSystemInfo>能完整的反应某一个目录下的所有的文件和文件夹,一个IList<DirectoryInfo>反应该文件夹下的所有子文件夹,一个IList<FileInfo>反应该文件夹下的所有文件,当我们对文件夹集合或者文件集合进行操作的时候,能动态的响应到所有子对象的集合上。

 

【问题分析】

在.net的类型定义里,虽然IList<>是一个泛型定义,而DirectoryInfo和FileInfo都是派生自FileSystemInfo,但IList<FileSystemInfo>和IList<FileInfo>与IList<DirectoryInfo>没有任何关系,也就是说,我们不能把一个IList<FileInfo>类型的集合对象或者IList<DirectoryInfo>类型的集合对象转换为IList<FileSystemInfo>类型,因此,简单的把实现需求变成了不可能。

 

【问题解决】

基于以上需求分析,决定定义一个集合代理类CollectionProxy<TSource, TBase>,该泛型类支持把TBase类型的集合对象转换为TSource类型的集合对象。

 

【代码实现】

1——

ICollectionEX接口定义

 

     ///   <summary>
    
///  扩展集合接口定义。本类接口定义等同于Collection实现的接口
    
///   </summary>
    
///   <typeparam name="T"></typeparam>
     public  interface ICollectionEx<T> : IList<T>, ICollection<T>, IEnumerable<T>, IList, ICollection, IEnumerable
    {
         ///   <summary>
        
///  新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
        
///   </summary>
         new  int Count {  get; }
         ///   <summary>
        
///  新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
        
///   </summary>
         new  void RemoveAt( int index);
         ///   <summary>
        
///  新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
        
///   </summary>
         new  void Clear();
         ///   <summary>
        
///  新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
        
///   </summary>
         new T  this[ int index] {  getset; }
         ///   <summary>
        
///  新定义属性或方法,避免在使用的时候引起基类的歧义,从而能简单的使用本类来达到目的
        
///   </summary>
         new  bool IsReadOnly {  get; }
    }

这个接口只是简单的把IList和ICollection两个集合(以及泛型集合)进行整合,考虑到IList与IList<>、ICollection与ICollection<>之间有方法、属性的冲突,因此,对冲突的属性和方法进行了重新定义,目的仅仅是为了避免在使用这个接口的时候出现歧义还需要再次进行转换

 

2——

CollectionProxy<T>集合的定义与实现

 

     public  class CollectionProxy<TData> : ICollection<TData>
    {
         private ICollection<TData> _baseCollection;

         protected ICollection<TData> BaseCollection
        {
             get
            {
                 return  this._baseCollection;
            }
        }

         public CollectionProxy(ICollection<TData> baseCollection)
        {
             if (baseCollection ==  null)
            {
                 throw  new ArgumentNullException( " baseCollection ");
            }
             this._baseCollection = baseCollection;
        }

         public  void Add(TData item)
        {
             this.AddItem(item);
        }

         protected  virtual  void AddItem(TData item) 
        {
             this.BaseCollection.Add(item);
        }


         public  void Clear()
        {
             this.ClearAll();
        }
         protected  virtual  void ClearAll() 
        {
             this.BaseCollection.Clear();
        }

         public  bool Contains(TData item)
        {
             return  this.ContainsItem(item);
        }
         protected  virtual  bool ContainsItem(TData item) 
        {
             return  this.BaseCollection.Contains(item);
        }
         public  void CopyTo(TData[] array,  int arrayIndex)
        {
             this.CopyItemTo(array, arrayIndex);
        }
         protected  virtual  void CopyItemTo(TData[] array,  int arrayIndex) 
        {
             this.BaseCollection.CopyTo(array, arrayIndex);
        }
         public  int Count
        {
             get
            {
                 return  this.BaseCollection.Count;
            }
        }

         public  bool IsReadOnly
        {
             get
            {
                 return  this.BaseCollection.IsReadOnly;
            }
        }

         public  bool Remove(TData item)
        {
           return   this.RemoveItem(item);
        }
         protected  virtual  bool RemoveItem(TData item) 
        {
             return  this.BaseCollection.Remove(item);
        }
         public IEnumerator<TData> GetEnumerator()
        {
             return  this.BaseCollection.GetEnumerator();
        }

         #region ICollection

         void ICollection<TData>.Add(TData item)
        {
             this.AddItem(item);
        }

         void ICollection<TData>.Clear()
        {
             this.ClearAll();
        }

         bool ICollection<TData>.Contains(TData item)
        {
             return  this.Contains(item);
        }

         void ICollection<TData>.CopyTo(TData[] array,  int arrayIndex)
        {
             this.CopyItemTo(array, arrayIndex);
        }

         int ICollection<TData>.Count
        {
             get
            {
                 return  this.Count;
            }
        }

         bool ICollection<TData>.IsReadOnly
        {
             get
            {
                 return  this.IsReadOnly;
            }
        }

         bool ICollection<TData>.Remove(TData item)
        {
             return  this.RemoveItem(item);
        }

         #endregion

         #region IEnumerable<TData>

        IEnumerator<TData> IEnumerable<TData>.GetEnumerator()
        {
             return  this.GetEnumerator();
        }

         #endregion

         #region IEnumerable

        IEnumerator IEnumerable.GetEnumerator()
        {
             return  this.GetEnumerator();
        }

         #endregion
    }

这个类是一个简单的ICollection<>泛型集合的代理类,目的就是实现一个可控的ICollection<>的集合对象。

3——

集合类CollectionExProxy<TData>

 

     public  class CollectionExProxy<TData> : CollectionProxy<TData>, ICollectionEx<TData>, INotifyPropertyChanged, INotifyCollectionChanged
    {
         #region 构造函数

         public CollectionExProxy(Collection<TData> baseCollection)
            :  base(baseCollection)
        {
        }

         protected  new Collection<TData> BaseCollection
        {
             get
            {
                 return  base.BaseCollection  as Collection<TData>;
            }
        }

         #endregion

         #region ICollectionEx<TData>

         int ICollectionEx<TData>.Count
        {
             get
            {
                 return ( this  as IList<TData>).Count;
            }
        }

         void ICollectionEx<TData>.RemoveAt( int index)
        {
            ( this  as IList<TData>).RemoveAt(index);
        }

         void ICollectionEx<TData>.Clear()
        {
            ( this  as IList<TData>).Clear();
        }

        TData ICollectionEx<TData>. this[ int index]
        {
             get
            {
                 return ( this  as IList<TData>)[index];
            }
             set
            {
                ( this  as IList<TData>)[index] = value;
            }
        }

         bool ICollectionEx<TData>.IsReadOnly
        {
             get
            {
                 return ( this  as IList<TData>).IsReadOnly;
            }
        }

         #endregion

         #region IList<TData>

         int IList<TData>.IndexOf(TData item)
        {
             return  this.BaseCollection.IndexOf(item);
        }

         void IList<TData>.Insert( int index, TData item)
        {
             this.BaseCollection.Insert(index, item);
        }

         void IList<TData>.RemoveAt( int index)
        {
             this.BaseCollection.RemoveAt(index);
        }

        TData IList<TData>. this[ int index]
        {
             get
            {
                 return  this.BaseCollection[index];
            }
             set
            {
                 this.BaseCollection[index] = value;
            }
        }

         #endregion

         #region IList

         int IList.Add( object value)
        {
             return ( this.BaseCollection  as IList).Add(value);
        }

         void IList.Clear()
        {
            ( this.BaseCollection  as IList).Clear();
        }

         bool IList.Contains( object value)
        {
             return ( this.BaseCollection  as IList).Contains(value);
        }

         int IList.IndexOf( object value)
        {
             return ( this.BaseCollection  as IList).IndexOf(value);
        }

         void IList.Insert( int index,  object value)
        {
            ( this.BaseCollection  as IList).Insert(index, value);
        }

         bool IList.IsFixedSize
        {
             get
            {
                 return ( this.BaseCollection  as IList).IsFixedSize;
            }
        }

         bool IList.IsReadOnly
        {
             get
            {
                 return ( this.BaseCollection  as IList).IsReadOnly;
            }
        }

         void IList.Remove( object value)
        {
            ( this.BaseCollection  as IList).Remove(value);
        }

         void IList.RemoveAt( int index)
        {
            ( this.BaseCollection  as IList).RemoveAt(index);
        }

         object IList. this[ int index]
        {
             get
            {
                 return ( this.BaseCollection  as IList)[index];
            }
             set
            {
                ( this.BaseCollection  as IList)[index] = value;
            }
        }

         #endregion

         #region ICollection

         void ICollection.CopyTo(Array array,  int index)
        {
            ( this.BaseCollection  as ICollection).CopyTo(array, index);
        }

         int ICollection.Count
        {
             get
            {
                 return ( this.BaseCollection  as ICollection).Count;
            }
        }

         bool ICollection.IsSynchronized
        {
             get
            {
                 return ( this.BaseCollection  as ICollection).IsSynchronized;
            }
        }

         object ICollection.SyncRoot
        {
             get
            {
                 return ( this.BaseCollection  as ICollection).SyncRoot;
            }
        }

         #endregion

         #region 事件处理

         event PropertyChangedEventHandler INotifyPropertyChanged.PropertyChanged
        {
            add
            {
                 if ( this.BaseCollection  is INotifyPropertyChanged)
                {
                    ( this.BaseCollection  as INotifyPropertyChanged).PropertyChanged += value;
                }
                 else
                {
                     throw  new InvalidOperationException( string.Format( " {0} is not implement interface {1}. "this.BaseCollection.GetType(),  typeof(INotifyPropertyChanged)));
                }
            }
            remove
            {
                 if ( this.BaseCollection  is INotifyPropertyChanged)
                {
                    ( this.BaseCollection  as INotifyPropertyChanged).PropertyChanged -= value;
                }
                 else
                {
                     throw  new InvalidOperationException( string.Format( " {0} is not implement interface {1}. "this.BaseCollection.GetType(),  typeof(INotifyPropertyChanged)));
                }
            }
        }

         event NotifyCollectionChangedEventHandler INotifyCollectionChanged.CollectionChanged
        {
            add
            {
                 if ( this.BaseCollection  is INotifyCollectionChanged)
                {
                    ( this.BaseCollection  as INotifyCollectionChanged).CollectionChanged += value;
                }
                 else
                {
                     throw  new InvalidOperationException( string.Format( " {0} is not implement interface {1}. "this.BaseCollection.GetType(),  typeof(INotifyCollectionChanged)));
                }
            }
            remove
            {
                 if ( this.BaseCollection  is INotifyCollectionChanged)
                {
                    ( this.BaseCollection  as INotifyCollectionChanged).CollectionChanged -= value;
                }
                 else
                {
                     throw  new InvalidOperationException( string.Format( " {0} is not implement interface {1}. "this.BaseCollection.GetType(),  typeof(INotifyCollectionChanged)));
                }
            }
        }

         #endregion
    }

这个类简单实现ICollectionEx<>这个接口,同时为便于对ObservableCollection<>的扩展,实现了INotifyPropertyChanged结合和INotifyCollectionChanged接口,代码都i很简单。

 

4——

CollectionProxy<TSource, TBase>类,这个类是目标,解决了需求中提到的问题。TSource和TBase之间可以没有任何的关系。TBase类型与TSource类型之间的转换,默认下是进行强制操作,其它情况下,可以通过在构造函数中传递两对象类型转换委托实现。具体代码如下:

 

     public  class CollectionProxy<TSource, TBase> : ICollectionEx<TSource>
    {
         #region 构造函数

         private ICollectionEx<TBase> _baseCollection;
        Func<TSource, TBase> _convertSourceToBaseHandler =  null;
        Func<TBase, TSource> _convertBaseToSourceHandler =  null;

         public CollectionProxy(Collection<TBase> baseCollection, Func<TSource, TBase> convertSourceToBaseHandler =  null, Func<TBase, TSource> convertBaseToSourceHandler =  null)
            :  this( new CollectionExProxy<TBase>(baseCollection), convertSourceToBaseHandler, convertBaseToSourceHandler)
        {
        }

         public CollectionProxy(ICollectionEx<TBase> baseCollection, Func<TSource, TBase> convertSourceToBaseHandler =  null, Func<TBase, TSource> convertBaseToSourceHandler =  null)
        {
             if (baseCollection ==  null)
            {
                 throw  new ArgumentNullException( " baseCollection ");
            }
             this._baseCollection = baseCollection;
            _convertSourceToBaseHandler = convertSourceToBaseHandler;
            _convertBaseToSourceHandler = convertBaseToSourceHandler;
        }

         #endregion

         #region 转换函数

         private TSource BaseToSourceHandler(TBase @base)
        {
             if ( this._convertBaseToSourceHandler !=  null)
            {
                 return  this._convertBaseToSourceHandler(@base);
            }
             return  this.BaseToSourceHandlerInternal(@base);
        }

         protected  virtual TSource BaseToSourceHandlerInternal(TBase @base)
        {
             return (TSource)( object)@base;
        }

         private TBase SourceToBaseHandler(TSource source)
        {
             if ( this._convertBaseToSourceHandler !=  null)
            {
                 return  this._convertSourceToBaseHandler(source);
            }
             return  this.SourceToBaseHandlerInternal(source);
        }

         protected  virtual TBase SourceToBaseHandlerInternal(TSource source)
        {
             return (TBase)( object)source;
        }

         #endregion

         #region 功能函数

         public  void Add(TSource item)
        {
             int count =  this.Count;
             this.InsertItem(count, item);
        }

         public  void Clear()
        {
             this.ClearItems();
        }

         protected  virtual  void ClearItems()
        {
             this.BaseCollection.Clear();
        }

         public  bool Contains(TSource item)
        {
             return  this.BaseCollection.Contains(SourceToBaseHandler(item));
        }

         public  void CopyTo(TSource[] array,  int index)
        {
             if (array ==  null)
            {
                 throw  new ArgumentNullException( " array ");
            }
            TBase[] tmp =  new TBase[array.Length];
             this.BaseCollection.CopyTo(tmp, index);
             for ( int i = index; i < index + ( this._baseCollection  as IList).Count; i++)
            {
                array[i] = BaseToSourceHandler(tmp[i]);
            }
        }

         public IEnumerator<TSource> GetEnumerator()
        {
             foreach ( var item  in  this._baseCollection)
            {
                 yield  return BaseToSourceHandler(item);
            }
        }

         public  int IndexOf(TSource item)
        {
             return  this.IndexOfItem(item);
        }

         protected  virtual  int IndexOfItem(TSource item)
        {
             return  this.BaseCollection.IndexOf(SourceToBaseHandler(item));
        }

         public  void Insert( int index, TSource item)
        {
             this.InsertItem(index, item);
        }

         protected  virtual  int InsertItem( int index, TSource item)
        {
             this.BaseCollection.Insert(index, SourceToBaseHandler(item));
             return index;
        }

         private  static  bool IsCompatibleObject( object value)
        {
             return ((value  is TSource) || ((value ==  null) && ( default(TSource) ==  null)));
        }

         public  bool Remove(TSource item)
        {
             int index =  this.IndexOf(item);
             if (index <  0)
            {
                 return  false;
            }
             this.RemoveItem(index);
             return  true;
        }

         public  void RemoveAt( int index)
        {
             this.RemoveItem(index);
        }

         protected  virtual  void RemoveItem( int index)
        {
             this.BaseCollection.RemoveAt(index);
        }

         protected  virtual  void SetItem( int index, TSource item)
        {
             this.BaseCollection[index] = SourceToBaseHandler(item);
        }

         public  int Count
        {
             get
            {
                 return  this.BaseCollection.Count;
            }
        }

         protected  virtual TSource GetValue( int index)
        {
             return BaseToSourceHandler( this.BaseCollection[index]);
        }

         public TSource  this[ int index]
        {
             get
            {
                 return  this.GetValue(index);
            }
             set
            {
                 this.SetItem(index, value);
            }
        }

         protected ICollectionEx<TBase> BaseCollection
        {
             get
            {
                 return  this._baseCollection;
            }
        }

         #endregion

         #region ICollectionEx<TSource>

         int ICollectionEx<TSource>.Count
        {
             get
            {
                 return ( this  as IList<TSource>).Count;
            }
        }

         void ICollectionEx<TSource>.RemoveAt( int index)
        {
            ( this  as IList<TSource>).RemoveAt(index);
        }

         void ICollectionEx<TSource>.Clear()
        {
            ( this  as IList<TSource>).Clear();
        }

        TSource ICollectionEx<TSource>. this[ int index]
        {
             get
            {
                 return ( this  as IList<TSource>)[index];
            }
             set
            {
                ( this  as IList<TSource>)[index] = value;
            }
        }

         bool ICollectionEx<TSource>.IsReadOnly
        {
             get
            {
                 return ( this  as IList<TSource>).IsReadOnly;
            }
        }

         #endregion

         #region IList<TSource>

         int IList<TSource>.IndexOf(TSource item)
        {
             return  this.IndexOf(item);
        }

         void IList<TSource>.Insert( int index, TSource item)
        {
             this.Insert(index, item);
        }

         void IList<TSource>.RemoveAt( int index)
        {
             this.RemoveAt(index);
        }

        TSource IList<TSource>. this[ int index]
        {
             get
            {
                 return  this[index];
            }
             set
            {
                 this[index] = value;
            }
        }

         #endregion

         #region ICollection<TSource>

         void ICollection<TSource>.Add(TSource item)
        {
             this.Add(item);
        }

         void ICollection<TSource>.Clear()
        {
             this.Clear();
        }

         bool ICollection<TSource>.Contains(TSource item)
        {
             return  this.Contains(item);
        }

         void ICollection<TSource>.CopyTo(TSource[] array,  int arrayIndex)
        {
             this.CopyTo(array, arrayIndex);
        }

         int ICollection<TSource>.Count
        {
             get
            {
                 return  this.Count;
            }
        }

         bool ICollection<TSource>.IsReadOnly
        {
             get
            {
                 return  this._baseCollection.IsReadOnly;
            }
        }

         bool ICollection<TSource>.Remove(TSource item)
        {
             return  this.Remove(item);
        }

         #endregion

         #region IEnumerable<TSource>

        IEnumerator<TSource> IEnumerable<TSource>.GetEnumerator()
        {
             return  this.GetEnumerator();
        }

         #endregion

         #region IEnumerable

        IEnumerator IEnumerable.GetEnumerator()
        {
             return  this.GetEnumerator();
        }

         #endregion

         #region IList

         int IList.Add( object value)
        {
             if (IsCompatibleObject(value))
            {
                 int index =  this.Count;
                 this.InsertItem(index, (TSource)value);
                 return index;
            }
             throw  new InvalidCastException();
        }

         void IList.Clear()
        {
             this.Clear();
        }

         bool IList.Contains( object value)
        {
             if (IsCompatibleObject(value))
            {
                 return  this.Contains((TSource)value);
            }
             return  false;
        }

         int IList.IndexOf( object value)
        {
             if (IsCompatibleObject(value))
            {
                 return  this.IndexOf((TSource)value);
            }
             return - 1;
        }

         void IList.Insert( int index,  object value)
        {
             if (IsCompatibleObject(value))
            {
                 this.Insert(index, (TSource)value);
            }
             else
            {
                 throw  new InvalidCastException();
            }
        }

         bool IList.IsFixedSize
        {
             get
            {
                 return  this.BaseCollection.IsFixedSize;
            }
        }

         bool IList.IsReadOnly
        {
             get
            {
                 return  this.BaseCollection.IsReadOnly;
            }
        }

         void IList.Remove( object value)
        {
             if (IsCompatibleObject(value))
            {
                 this.Remove((TSource)value);
            }
             else
            {
                 throw  new InvalidCastException();
            }
        }

         void IList.RemoveAt( int index)
        {
             this.RemoveAt(index);
        }

         object IList. this[ int index]
        {
             get
            {
                 return  this[index];
            }
             set
            {
                 if (IsCompatibleObject(value))
                {
                     this[index] = (TSource)value;
                }
                 else
                {
                     throw  new InvalidCastException();
                }
            }
        }

         #endregion

         #region ICollection

         void ICollection.CopyTo(Array array,  int index)
        {
            TSource[] tmp =  new TSource[array.Length];
             this.CopyTo(tmp, index);
             for ( int i = index; i < array.Length; i++)
            {
                array.SetValue(tmp[i], i);
            }
        }

         int ICollection.Count
        {
             get
            {
                 return  this.Count;
            }
        }

         bool ICollection.IsSynchronized
        {
             get
            {
                 return  this.BaseCollection.IsSynchronized;
            }
        }

         object ICollection.SyncRoot
        {
             get
            {
                 return  this.BaseCollection.SyncRoot;
            }
        }

         #endregion
    }

这个类在构造的时候

5——

一个对应的只读类ReadOnlyCollectionEx的实现

 

     public  class ReadOnlyCollectionEx<T> : ICollectionEx<T>
    {
         #region 构造函数

        [NonSerialized]
         private  object _syncRoot;
         private IList<T>[] _lists;

         public ReadOnlyCollectionEx(IList<T> list,  params IList<T>[] lists)
        {
             if (list ==  null)
            {
                 throw  new ArgumentNullException( " list ");
            }
             this._lists =  new IList<T>[lists.Length +  1];
            _lists[ 0] = list;
             for ( int i =  0; i < lists.Length; i++)
            {
                 if (lists[i] ==  null)
                {
                     throw  new ArgumentNullException( " lists "" 顺序号为 {0} 的对象为空。 ".FormatWith(i));
                }
                _lists[i +  1] = lists[ 0];
            }
        }

         #endregion

         #region 基本操作

        [TargetedPatchingOptOut( " Performance critical to inline across NGen image boundaries ")]
         public  bool Contains(T value)
        {
             return  this.ContainsInternal(value);
        }

         protected  virtual  bool ContainsInternal(T value)
        {
             return  this.IndexOf(value) >=  0;
        }

         public  void CopyTo(Array array,  int index)
        {
             if (array ==  null)
            {
                 throw  new ArgumentNullException( " array ");
            }
             if (array.Rank !=  1)
            {
                 throw  new ArgumentOutOfRangeException( " array "" 只支持一维数组。 ");
            }
             if (array.GetLowerBound( 0) !=  0)
            {
                 throw  new ArgumentOutOfRangeException( " array "" 只支持0基数组。 ");
            }
             if (index <  0)
            {
                 throw  new ArgumentOutOfRangeException( " index "" 不能为负数 ");
            }
             if ((array.Length - index) <  this.Count)
            {
                 throw  new ArgumentOutOfRangeException( " array, index "" 数组空间不足 ");
            }
             this.CopyToInternal(array, index);
        }

         protected  virtual  void CopyToInternal(Array array,  int index)
        {
             for ( int i =  0; i <  this.Count; i++)
            {
                array.SetValue( this[i], index + i);
            }
        }

         public  int IndexOf(T value)
        {
             return  this.IndexOfInternal(value);
        }

         protected  virtual  int IndexOfInternal(T value)
        {
             int index =  0;
             for ( int i =  0; i <  this._lists.Length; i++)
            {
                 int currentIndex =  this._lists[i].IndexOf(value);
                 if (currentIndex >=  0)
                {
                     return index + currentIndex;
                }
                 else
                {
                    index +=  this._lists[i].Count;
                }
            }
             return - 1;
        }

         public  int Count
        {
             get
            {
                 return  this.CountInternal;
            }
        }

         protected  virtual  int CountInternal
        {
            [TargetedPatchingOptOut( " Performance critical to inline across NGen image boundaries ")]
             get
            {
                 int count =  0;
                 for ( int i =  0; i <  this._lists.Length; i++)
                {
                    count += _lists[i].Count;
                }
                 return count;
            }
        }

         public T  this[ int index]
        {
             get
            {
                 if (index <  0)
                {
                     throw  new ArgumentOutOfRangeException( " index ");
                }
                 return  this.GetDataItem(index);
            }
        }

         protected  virtual T GetDataItem( int index)
        {
             int tmp = index;
             for ( int i =  0; i <  this._lists.Length; i++)
            {
                 if (tmp <  this._lists[i].Count)
                {
                     return  this._lists[i][tmp];
                }
                tmp -= _lists[i].Count;
            }
             throw  new ArgumentOutOfRangeException( " index ");
        }

         public IEnumerator<T> GetEnumerator()
        {
             return  this.GetEnumeratorInternal();
        }

         protected  virtual IEnumerator<T> GetEnumeratorInternal()
        {
             for ( int i =  0; i <  this._lists.Length; i++)
            {
                 for ( int j =  0; j <  this._lists[i].Count; j++)
                {
                     yield  return  this._lists[i][j];
                }
            }
        }

         private  static  bool IsCompatibleObject( object value)
        {
             return ((value  is T) || ((value ==  null) && ( default(T) ==  null)));
        }

         protected IList<T>[] Items
        {
             get
            {
                 return  this._lists;
            }
        }

         #endregion

         #region 获取枚举集合操作

        IEnumerator<T> IEnumerable<T>.GetEnumerator()
        {
             return  this.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
             return  this.GetEnumerator();
        }

         #endregion

         #region 禁止写操作

         void ICollection<T>.Add(T value)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         void ICollection<T>.Clear()
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         bool ICollection<T>.Remove(T value)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         void IList<T>.Insert( int index, T value)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         void IList<T>.RemoveAt( int index)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         #endregion

         #region 接口其它实现

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

         void ICollection<T>.CopyTo(T[] array,  int index)
        {
             this.CopyTo(array, index);
        }

         int IList.Add( object value)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         void IList.Clear()
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         bool IList.Contains( object value)
        {
             return (ReadOnlyCollectionEx<T>.IsCompatibleObject(value) &&  this.Contains((T)value));
        }

         int IList.IndexOf( object value)
        {
             if (IsCompatibleObject(value))
            {
                 return  this.IndexOf((T)value);
            }
             return - 1;
        }

         void IList.Insert( int index,  object value)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         void IList.Remove( object value)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         void IList.RemoveAt( int index)
        {
             throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
        }

         bool ICollection<T>.IsReadOnly
        {
             get
            {
                 return  true;
            }
        }

        T IList<T>. this[ int index]
        {
             get
            {
                 return  this[index];
            }
             set
            {
                 throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
            }
        }

         bool ICollection.IsSynchronized
        {
             get
            {
                 return  false;
            }
        }

         object ICollection.SyncRoot
        {
             get
            {
                 if ( this._syncRoot ==  null)
                {
                    ICollection list =  this._lists  as ICollection;
                     if (list !=  null)
                    {
                         this._syncRoot = list.SyncRoot;
                    }
                     else
                    {
                        Interlocked.CompareExchange< object>( ref  this._syncRoot,  new  object(),  null);
                    }
                }
                 return  this._syncRoot;
            }
        }

         bool IList.IsFixedSize
        {
             get
            {
                 return  true;
            }
        }

         bool IList.IsReadOnly
        {
             get
            {
                 return  true;
            }
        }

         object IList. this[ int index]
        {
            [TargetedPatchingOptOut( " Performance critical to inline across NGen image boundaries ")]
             get
            {
                 return  this[index];
            }
             set
            {
                 throw  new NotImplementedException( " 只读集合,禁止操作对象。 ");
            }
        }

         #endregion

         #region ICollectionEx<T>

         int ICollectionEx<T>.Count
        {
             get
            {
                 return ( this  as IList<T>).Count;
            }
        }

         void ICollectionEx<T>.RemoveAt( int index)
        {
            ( this  as IList<T>).RemoveAt(index);
        }

         void ICollectionEx<T>.Clear()
        {
            ( this  as IList<T>).Clear();
        }

        T ICollectionEx<T>. this[ int index]
        {
             get
            {
                 return ( this  as IList<T>)[index];
            }
             set
            {
                ( this  as IList<T>)[index] = value;
            }
        }

         bool ICollectionEx<T>.IsReadOnly
        {
             get
            {
                 return ( this  as IList<T>).IsReadOnly;
            }
        }

         #endregion

    }

这个类只是简单的实现ICollectionEx接口对象的只读化处理,与系统ReadOnlyCollection<>类不同的是,该类支持多个原始数据集合类的构造,可以把多个原始集合类集成为一个统一的集合类对外提供服务。

 

在输出数据集合的时候,该类默认按照集合的顺序逐个输出,也就是说,先按照集合排队,再按照子集合内部的顺序输出。基于LINQ的原因,集合的顺序可以任意排列。

 

 

【应用示例】

一个前面提到的文件系统的需求的实现:

 

         private Collection<FileSystemInfo> _foldersBase =  new Collection<FileSystemInfo>();
         private ICollectionEx<DirectoryInfo> _folders;
         public ICollectionEx<DirectoryInfo> Folders
        {
             get
            {
                 if ( this._folders ==  null)
                {
                     this._folders =  new CollectionProxy<DirectoryInfo, FileSystemInfo>(_foldersBase);
                }
                 return _folders;
            }
        }

         private Collection<FileSystemInfo> _filesBase =  new Collection<FileSystemInfo>();
         private ICollectionEx<FileInfo> _files;
         public ICollectionEx<FileInfo> Files
        {
             get
            {
                 if ( this._files ==  null)
                {
                     this._files =  new CollectionProxy<FileInfo, FileSystemInfo>(_filesBase);
                }
                 return _files;
            }
        }

         private ReadOnlyCollectionEx<FileSystemInfo> _children;
         public ReadOnlyCollectionEx<FileSystemInfo> Children
        {
             get
            {
                 if ( this._children ==  null)
                {
                     this._children =  new ReadOnlyCollectionEx<FileSystemInfo>(_foldersBase, _filesBase);
                }
                 return  this._children;
            }
        }

 

 

 

你可能感兴趣的:(集合代理类的实现)