C#集合:ICollection和IList接口
虽然枚举接口IEnumerable
提供了一种向前迭代集合的协议,但是它们并没有提供确定集合大小、根据索引访问成员、搜索以及修改集合的机制。为了实现这些功能,.NET Core定义了ICollection
、IList
和IDictionary
接口。这些接口都支持泛型和非泛型版本。然而,非泛型版本的存在只是为了兼容遗留代码。
可以简单总结为:
IEnumerable<T>(和IEnumerable)
:提供了最少的功能支持(仅支持元素枚举)。ICollection<T>(和ICollection)
:提供一般的功能(例如Count属性)。IList<T>/IDictionary<K, V>
及其非泛型版本:支持最多的功能(包括根据索引/键进行“随机”访问)。
ICollection<T>和ICollection
ICollection<T>
是可以对其中的对象进行计数的标准集合接口。它可以确定集合大小(Count),确定集合中是否存在某个元素(Contains),将集合复制到一个数组(ToArray)以及确定集合是否为只读(IsReadOnly)。对于可写集合,还可以对集合元素进行添加(Add)、删除(Remove)以及清空(Clear)操作。由于它扩展自IEnumerable<T>
,因此也可以通过foreach语句进行遍历。
public interface ICollection<T> : IEnumerable<T>, IEnumerable { int Count { get; } bool IsReadOnly { get; } void Add(T item); void Clear(); bool Contains(T item); void CopyTo(T[] array, int arrayIndex); bool Remove(T item); }
非泛型的ICollection也提供了计数的功能,但是它并不支持修改或检查集合元素的功能:
public interface ICollection : IEnumerable { int Count { get; } object SyncRoot { get; } bool IsSynchronized { get; } void CopyTo(Array array, int index); }
IList<T>和IList
IList<T>
是按照位置对集合进行索引的标准接口。除了从ICollection<T>
和IEnumerable<T>
继承的功能之外,它还可以按位置(通过索引器)读写元素,并在特定位置插入/删除元素。
public interface IList<T> : ICollection<T>, IEnumerable<T>, IEnumerable { T this[int index] { get; set; } int IndexOf(T item); void Insert(int index, T item); void RemoveAt(int index); }
IndexOf
方法可以对列表执行线性搜索,如果未找到指定的元素则返回-1。
IList
的非泛型版本具有更多的成员,因为(相比泛型版本)它从ICollection
继承过来的成员比较少:
public interface IList : ICollection, IEnumerable { object this[int index] { get; set; } bool IsReadOnly { get; } bool IsFixedSize { 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); }
非泛型的IList
接口的Add
方法会返回一个整数代表最新添加元素的索引。相反,ICollection<T>
的Add
方法的返回类型为void
。
通用的List<T>
类实现了IList<T>
和IList
两种接口。C#的数组同样实现了泛型和非泛型版本的IList接口。
IReadOnlyCollection<T>与IReadOnlyList<T>
.NET Core同样定义了一系列仅提供只读操作的集合及列表接口:
public interface IReadOnlyCollection<out T> : IEnumerable<T>, IEnumerable { int Count { get; } } public interface IReadOnlyList<out T> : IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable { T this[int index] { get; } }
由于上述接口的类型参数仅仅在输出时使用,因此被标记为协变参数。这样我们就可以将一个“猫咪”的列表表示为一个“动物”的只读列表。
相反,在IList<T>
和ICollection<T>
中,由于T在输入输出时均被使用,因此没有标记为协变参数。
本文来自博客园,作者:一纸年华,转载请注明原文链接:https://www.cnblogs.com/nullcodeworld/p/16627354.html
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 记一次.NET内存居高不下排查解决与启示
· DeepSeek 开源周回顾「GitHub 热点速览」
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了