为何通过接口创建对象?以IList与List为例解析差异
接口声明 vs 具体类声明:IList/ICollection 和 List/Collection 的区别
嘿,这个问题问得特别好——很多刚接触C#集合的开发者都会有这个困惑,我来一步步给你掰扯清楚:
一、IList<string> People = new List<string>(); 和 List<string> People = new List<string>(); 的核心区别
这两种写法本质是面向接口编程 vs 面向具体类编程,差异主要体现在这几点:
- 灵活性拉满:如果用
IList<T>声明,后续你可以轻松把实现换成其他IList<T>的子类,比如ObservableCollection<string>或者自定义的集合类,完全不用修改调用这个变量的所有代码。比如哪天你需要集合变更通知,直接改成new ObservableCollection<string>()就行,上层代码连动都不用动。 - 暴露的功能不同:
IList<T>只定义了集合的通用接口(比如Add、Remove、Count、索引器),而List<T>还有自己的专属方法(比如AddRange、FindAll、Sort这些)。用接口声明的话,你只能调用接口里定义的方法,相当于“隐藏”了具体类的额外功能,强迫自己依赖抽象而非具体实现,这也是SOLID原则里的依赖倒置原则。 - 场景适配性:如果这个变量是作为方法参数或者返回值,用接口声明会让方法的通用性更强——比如一个接收
IList<T>的方法,能处理所有实现了这个接口的集合,而不只是List<T>。但如果你的代码确实需要用到List<T>的专属方法(比如批量排序),那直接声明成List<T>更方便,不用来回强制转类型。
二、关于Collection<string> People = new Collection<string>();的写法
当然可以直接这么写!首先得明确:ICollection<T>是接口,而Collection<T>是.NET提供的一个具体类(它实现了ICollection<T>、IList<T>等多个接口)。
为什么有人会直接用Collection<T>呢?原因有这些:
Collection<T>是一个专为扩展设计的基础集合类,它比List<T>更适合用来创建自定义集合——如果你想写自己的集合类,继承Collection<T>会比继承List<T>优雅得多,因为它预留了InsertItem、RemoveItem等虚方法,方便你重写集合的变更逻辑;而List<T>的大部分方法都是非虚的,扩展起来特别麻烦。- 如果你的代码不需要后续替换集合实现,也不需要依赖抽象接口,直接用
Collection<T>完全没问题,它本身就是一个合法的具体实现类,和List<T>一样可以直接实例化。
三、总结:什么时候用哪种写法
- 优先用接口声明(比如
IList<T>、ICollection<T>):当你需要代码的灵活性、扩展性,或者这个变量是对外暴露的(方法参数、返回值、类的公共属性),遵循面向抽象编程的原则,减少代码耦合。 - 用具体类声明(比如
List<T>、Collection<T>):当你明确需要使用该类的专属方法,或者这个变量只是内部私有变量,不需要考虑后续替换实现的时候,直接用具体类更省事。
内容的提问来源于stack exchange,提问作者Megawatt
相关产品推荐
相关产品推荐

