为什么 ReadOnlyCollection<T> 不是 ReadOnlyList<T>?

ord*_*dag 5 .net collections readonly

我认为IEnumerable事物是您可以迭代的对象。
如果它们也是ICollections,你就会知道里面有多少元素。
如果它们是偶数,IList您可以从特定索引中获取包含对象。

一个ReadOnlyCollection<T>实现IList<T>。所以不会ReadOnlyList<T>是一个更好的名字。

ReadOnlyCollection<T>框架中有真实的吗?
(所以我不需要 IList 来创建这样的只读包装器)

ord*_*dag 0

namespace System.Collections.ObjectModel
{
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.Runtime.InteropServices;
    using System.Threading;

    internal sealed class CollectionDebugView<T>
    {
        private readonly ICollection<T> collection;

        public CollectionDebugView(ICollection<T> collection)
        {
            if (collection == null) { throw new ArgumentNullException("collection"); }

            this.collection = collection;
        }

        [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
        public T[] Items
        {
            get
            {
                T[] items = new T[this.collection.Count];
                this.collection.CopyTo(items, 0);
                return items;
            }
        }
    }

    [Serializable]
    [ComVisible(false)]
    [DebuggerDisplay("Count = {Count}")]
    [DebuggerTypeProxy(typeof(CollectionDebugView<>))]
    public class ReadOnlyCollection<T> : ICollection<T>, ICollection
    {
        private readonly ICollection<T> genericCollection;
        private readonly ICollection nongenericCollection;

        [NonSerialized]
        private object syncRoot;

        public ReadOnlyCollection(ICollection<T> collection)
        {
            if (collection == null) { throw new ArgumentNullException("collection"); }

            this.genericCollection = collection;
            this.nongenericCollection = collection as ICollection;
        }

        void ICollection<T>.Add(T item)
        {
            throw new NotSupportedException();
        }

        void ICollection<T>.Clear()
        {
            throw new NotSupportedException();
        }

        public bool Contains(T item)
        {
            return this.genericCollection.Contains(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            this.genericCollection.CopyTo(array, arrayIndex);
        }

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

        public bool IsReadOnly
        {
            get { return true; }
        }

        bool ICollection<T>.Remove(T item)
        {
            throw new NotSupportedException();
        }

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

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

        void ICollection.CopyTo(Array array, int index)
        {
            if (this.nongenericCollection == null)
            {
                if (array == null) { throw new ArgumentNullException("array"); }
                if (array.Rank != 1) { throw new ArgumentException(); }
                if (array.GetLowerBound(0) != 0) { throw new ArgumentException(); }
                if (index < 0) { throw new ArgumentOutOfRangeException(); }
                if (array.Length < index + this.genericCollection.Count) { throw new ArgumentException(); }

                T[] typedArray = array as T[];

                if (typedArray == null)
                {
                    Type arrayType = array.GetType().GetElementType();
                    Type collectionType = typeof(T);

                    if (arrayType.IsAssignableFrom(collectionType) || collectionType.IsAssignableFrom(arrayType))
                    {
                        object[] objectArray = array as object[];

                        if (objectArray == null) { throw new ArgumentException(); }

                        try
                        {
                            foreach (T item in this.genericCollection)
                            {
                                objectArray[index] = item;
                                index++;
                            }
                        }
                        catch (ArrayTypeMismatchException)
                        {
                            throw new ArgumentException();
                        }

                    }
                    else
                    {
                        throw new ArgumentException();
                    }
                }
                else
                {
                    this.genericCollection.CopyTo(typedArray, index);
                }
            }
            else
            {
                this.nongenericCollection.CopyTo(array, index);
            }
        }

        int ICollection.Count
        {
            get { return this.nongenericCollection == null ? this.genericCollection.Count : this.nongenericCollection.Count; }
        }

        bool ICollection.IsSynchronized
        {
            get { return this.nongenericCollection == null ? false : this.nongenericCollection.IsSynchronized; }
        }

        object ICollection.SyncRoot
        {
            get
            {
                if (this.syncRoot == null)
                {
                    if (this.nongenericCollection == null)
                    {
                        this.syncRoot = this.nongenericCollection.SyncRoot;
                    }
                    else
                    {
                        Interlocked.CompareExchange<object>(ref this.syncRoot, new object(), null);
                    }
                }

                return this.syncRoot;
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)