美文网首页
C#容器——一些接口和基类

C#容器——一些接口和基类

作者: 太刀 | 来源:发表于2021-01-31 11:10 被阅读0次

    C# 提供了多种容器来存放数据,并提供数据的增删改查等功能,容器所实现的接口规范了容器所具有的的行为和能力,下面列举一些 C# 容器相关的接口

    1. 接口 IEnumerator

    枚举器或迭代器,实现该接口的类可以用来迭代,也就是遍历容器,看源码

    
    public interface IEnumerator
    
    {
    
    object Current { get; }
    
    bool MoveNext();
    
    void Reset();
    
    }
    
    
    • 属性Current返回当前元素

    • 方法MoveNext 将迭代器指针指向下一个元素,并返回下一个元素是否为空

    • 方法 Reset 重置迭代器到第一个元素的前方

    2. 接口 IEnumerable

    实现此接口的类可以被迭代或遍历,看源码

    
        public interface IEnumerable
    
        {
    
            [DispId(-4)]
    
            IEnumerator GetEnumerator();
    
        }
    
    
    • 只有一个返回迭代器的方法

    C# 中的数据容器基本都是可以被遍历的,所以容器类都实现了 IEnumerable接口,我们通常用 foreach 来遍历容器,foreach 实际上只是一个语法糖,编译时是通过获取容器的迭代器,调用 MoveNext 方法来实现的遍历,例如下面这段代码:

    
            Array a = new int[100];                             
    
            foreach(int v in a)
    
            {
    
                Debug.Log(v);
    
            }
    
            IEnumerator enumerator = a.GetEnumerator();
    
            while (enumerator.MoveNext())
    
            {
    
                Debug.Log(enumerator.Current);
    
            }
    
    

    3. 接口 IComparer

    实现此接口的类可以进行元素的比较,看源码

    
        public interface IComparer
    
        {
    
            int Compare(object x, object y);
    
        }
    
    

    我们经常需要对容器中的元素进行排序,那么排序的依据就是一个实现了 IComparer接口的类对象,例如,Array 容器实现了 IStructuralComparable 接口,该接口的源码是

    
        public interface IStructuralComparable
    
        {
    
            int CompareTo(object other, IComparer comparer);
    
        }
    
    

    也就是说,Array容器的元素需要能和其它元素进行比较得出结果,而比较的逻辑由传入的 IComparer类参数确定

    4. 接口 IEqualityComparer

    实现此接口的类可以比较元素是否相等,看源码

    
        [ComVisible(true)]
    
        public interface IEqualityComparer
    
        {
    
            bool Equals(object x, object y);
    
            int GetHashCode(object obj);
    
        }
    
    
    • 方法 Equals 定义两个元素相等性的判断逻辑

    • 方法 GetHashCode 定义如何计算元素的 Hash 值

    在使用容器时经常需要判断容器中的元素是否相等,这里的相等行为通常是可定制的,可以通过实现 IEqualityComparer 对应的方法来定制比较接口,例如,Array 容器实现了 IStructuralEquatable 接口,该接口的源码是

    
        public interface IStructuralEquatable
    
        {
    
            bool Equals(object other, IEqualityComparer comparer);
    
            int GetHashCode(IEqualityComparer comparer);
    
        }
    
    

    也就是说,Array容器的元素可以判定是否和另外一个元素相等,判断逻辑由传入的 IEqualityComparer参数确定,同样也可以定义元素 Hash 值的计算逻辑

    5. 接口 ICloneable

    实现此接口的类可以被复制,源码:

    
        public interface ICloneable
    
        {
    
            object Clone();
    
        }
    
    

    复制的行为完全由 Clone 方法来定义,例如我们可以自己让自己的容器集成 ICloneable,通过实现 Clone方法类定义我们的容器被复制时,是深复制还是浅复制

    6. 接口 ICollection

    此接口是 IEnumerable 的加强接口,所以肯定是能够被迭代遍历的,源码

    
        public interface ICollection : IEnumerable
    
        {
    
            int Count { get; }
    
            bool IsSynchronized { get; }
    
            object SyncRoot { get; }
    
            void CopyTo(Array array, int index);
    
        }
    
    

    IEnumerable 接口的基础上,需提供获取元素数量、复制容器的接口,ICollection 是泛型接口,可以通过泛型参数来实现,如

    
    public interface ICollection<T> : IEnumerable<T>
    
        {
    
            // Number of items in the collections.       
    
            int Count { get; }
    
            bool IsReadOnly { get; }
    
            void Add(T item);
    
            void Clear();
    
            bool Contains(T item);
    
    
    
            // CopyTo copies a collection into an Array, starting at a particular
    
            // index into the array.
    
            //
    
            void CopyTo(T[] array, int arrayIndex);
    
    
    
            //void CopyTo(int sourceIndex, T[] destinationArray, int destinationIndex, int count);
    
            bool Remove(T item);
    
        }
    
    

    7. 接口 IList

    此接口描述列表容器应该具备的能力,看源码:

    
        public interface IList : ICollection, IEnumerable
    
        {
    
            object this[int index] { get; set; }
    
            bool IsFixedSize { get; }
    
            bool IsReadOnly { get; }
    
            int Add(object value);
    
            void Clear();
    
            bool Contains(object value);
    
            int IndexOf(object value);
    
            void Insert(int index, object value);
    
            void Remove(object value);
    
            void RemoveAt(int index);
    
        }
    
    

    除具备 ICollectionIEnumerable 提供的能力外,还包括:

    • 通过下标访问元素

    • 是否固定大小

    • 是否只读

    • 向列条添加元素 Add

    • 在某位置插入元素 Insert

    • 删除元素 Remove

    • 删除某个位置的元素 RemoveAt

    • 获得某个元素的下标 IndexOf

    • 清空列表 Clear

    我们平时写代码时,如何选择合适的容器呢?需要考虑

    • 存储元素,额外的存储空间

    • 添加、插入、删除元素的时间复杂度

    • 查找元素的效率

    相关文章

      网友评论

          本文标题:C#容器——一些接口和基类

          本文链接:https://www.haomeiwen.com/subject/ghsjtltx.html