集合代理类的实现

【问题的提出】

以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;
            }
        }

 

 

 

posted @ 2011-11-05 11:29 无之无 阅读(...) 评论(...) 编辑 收藏