美文网首页
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

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

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

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

  • 查找元素的效率

相关文章

  • 面向对象原则

    一、区分变与不变 不变为基类变为接口 二、能够复用和拓展 复用为基类拓展为接口 三、针对接口编程 抽象基类中有接口...

  • laravel如何自定义实现Facade(门面模式)

    Facades为程序的服务容器提供了可用的类提供了一个静态接口。laravel中Facades作为服务容器内基类的...

  • C++小知识点

    1.C++中类可以多继承 即一个子类继承多个父类,而在C#和java中,可以多继承多个接口,但是不能多继承多个基类...

  • 设计模式5--bridge(桥模式)

    bridge(桥模式) 基类Implementor,定义一些操作接口 基类Abstraction有指向Implem...

  • Java知识点整理(2)-容器

    容器的基本概念 Collection函数库是util包下的一些接口和类,类用来产生对象存放数据,接口是访问数据的方...

  • 2018年9月26日.NET笔试面试题

    C#中的接口和类有什么异同? 不同点 不能直接实例化接口。 接口不包含方法的实现。 接口可以多继承,类只能单继承。...

  • 10-27学习总结

    今天继续学习了C#第四章 1.接口是引用类型,是一系列需要实现的功能的定义。 接口类似于抽象基类,接口不能实例化 ...

  • 一个自用的简单MVP封装

    基本的View接口:IBaseView Presenter基类:IBasePresenter Activity基类...

  • C#——访问基类的成员

    1.基类与派生类之间的转换C#允许派生类转换为基类,但不允许把基类转换为派生类。这样,一个基类的对象即可以指向基类...

  • Lession09抽象类和接口

    抽象类 继承练习 接口 继承基类并实现接口

网友评论

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

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