C# List<T> 或 IList<T>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/400135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
List<T> or IList<T>
提问by Peanut
Can anyone explain to me why I would want to use IList over List in C#?
谁能向我解释为什么我想在 C# 中使用 IList 而不是 List?
Related question: Why is it considered bad to expose List<T>
相关问题:为什么认为暴露不好List<T>
采纳答案by tvanfosson
If you are exposing your class through a library that others will use, you generally want to expose it via interfaces rather than concrete implementations. This will help if you decide to change the implementation of your class later to use a different concrete class. In that case the users of your library won't need to update their code since the interface doesn't change.
如果您通过其他人将使用的库公开您的类,您通常希望通过接口而不是具体实现来公开它。如果您决定稍后更改类的实现以使用不同的具体类,这将有所帮助。在这种情况下,您的库的用户不需要更新他们的代码,因为界面不会改变。
If you are just using it internally, you may not care so much, and using List<T>
may be ok.
如果你只是在内部使用它,你可能不会那么在意,使用List<T>
可能没问题。
回答by Diadistis
IList<T> is an interface so you can inherit another class and still implement IList<T> while inheriting List<T> prevents you to do so.
IList<T> 是一个接口,因此您可以继承另一个类并仍然实现 IList<T> 而继承 List<T> 阻止您这样做。
For example if there is a class A and your class B inherits it then you can't use List<T>
例如,如果有一个类 A 并且您的类 B 继承它,那么您不能使用 List<T>
class A : B, IList<T> { ... }
回答by Peter Lindholm
You would because defining an IList or an ICollection would open up for other implementations of your interfaces.
您会这样做,因为定义 IList 或 ICollection 将为您的接口的其他实现打开。
You might want to have an IOrderRepository that defines a collection of orders in either a IList or ICollection. You could then have different kinds of implementations to provide a list of orders as long as they conform to "rules" defined by your IList or ICollection.
您可能希望有一个 IOrderRepository 来定义 IList 或 ICollection 中的订单集合。然后,您可以使用不同类型的实现来提供订单列表,只要它们符合您的 IList 或 ICollection 定义的“规则”。
回答by annakata
A principle of TDD and OOP generally is programming to an interface not an implementation.
TDD 和 OOP 的原则通常是对接口进行编程,而不是对实现进行编程。
In this specific case since you're essentially talking about a language construct, not a custom one it generally won't matter, but say for example that you found List didn't support something you needed. If you had used IList in the rest of the app you could extend List with your own custom class and still be able to pass that around without refactoring.
在这种特定情况下,由于您本质上是在谈论一种语言结构,而不是自定义结构,因此通常无关紧要,但例如,您发现 List 不支持您需要的某些东西。如果您在应用程序的其余部分使用了 IList,您可以使用您自己的自定义类扩展 List,并且仍然能够在不重构的情况下传递它。
The cost to do this is minimal, why not save yourself the headache later? It's what the interface principle is all about.
这样做的成本是最低的,为什么不让自己稍后再头疼呢?这就是接口原理的全部内容。
回答by smack0007
public void Foo(IList<Bar> list)
{
// Do Something with the list here.
}
In this case you could pass in any class which implements the IList<Bar> interface. If you used List<Bar> instead, only a List<Bar> instance could be passed in.
在这种情况下,您可以传入任何实现 IList<Bar> 接口的类。如果您改用 List<Bar>,则只能传入 List<Bar> 实例。
The IList<Bar> way is more loosely coupled than the List<Bar> way.
IList<Bar> 方式比 List<Bar> 方式更松散耦合。
回答by Michael Borgwardt
The most important case for using interfaces over implementations is in the parameters to your API. If your API takes a List parameter, then anyone who uses it has to use List. If the parameter type is IList, then the caller has much more freedom, and can use classes you never heard about, which may not even have existed when your code was written.
使用接口而不是实现的最重要的情况是 API 的参数。如果您的 API 采用 List 参数,那么使用它的任何人都必须使用 List。如果参数类型是 IList,那么调用者有更多的自由,并且可以使用您从未听说过的类,这些类在您编写代码时甚至可能不存在。
回答by ILoveFortran
List<T>
is a specific implementation of IList<T>
, which is a container that can be addressed the same way as a linear array T[]
using an integer index. When you specify IList<T>
as the type of the method's argument, you only specify that you need certain capabilities of the container.
List<T>
是 的特定实现IList<T>
,它是一个容器,可以T[]
使用整数索引以与线性数组相同的方式进行寻址。当您指定IList<T>
方法参数的类型时,您只需指定您需要容器的某些功能。
For example, the interface specification does not enforce a specific data structure to be used. The implementation of List<T>
happens to the same performance for accessing, deleting and adding elements as a linear array. However, you could imagine an implementation that is backed by a linked list instead, for which adding elements to the end is cheaper (constant-time) but random-access much more expensive. (Note that the .NET LinkedList<T>
does notimplement IList<T>
.)
例如,接口规范不强制使用特定的数据结构。的实现与List<T>
线性数组访问、删除和添加元素的性能相同。但是,您可以想象一个由链表支持的实现,为此,将元素添加到末尾更便宜(恒定时间),但随机访问更昂贵。(请注意,.NETLinkedList<T>
并没有实现IList<T>
。)
This example also tells you that there may be situations when you need to specify the implementation, not the interface, in the argument list: In this example, whenever you require a particular access performance characteristic. This is usually guaranteed for a specific implementation of a container (List<T>
documentation: "It implements the IList<T>
generic interface using an array whose size is dynamically increased as required.").
此示例还告诉您,可能存在需要在参数列表中指定实现而非接口的情况: 在此示例中,每当您需要特定访问性能特征时。这通常是针对容器的特定实现来保证的(List<T>
文档:“它IList<T>
使用大小根据需要动态增加的数组来实现通用接口。”)。
Additionally, you might want to consider exposing the least functionality you need. For example. if you don't need to change the content of the list, you should probably consider using IEnumerable<T>
, which IList<T>
extends.
此外,您可能需要考虑公开所需的最少功能。例如。如果您不需要更改列表的内容,您可能应该考虑使用IEnumerable<T>
,它IList<T>
扩展了。
回答by Rinat Abdullin
Interface is a promise(or a contract).
接口是一个承诺(或合同)。
As it is always with the promises - smaller the better.
正如承诺一样——越小越好。
回答by Patrik H?gne
I would turn the question around a bit, instead of justifying why you should use the interface over the concrete implementation, try to justify why you would use the concrete implementation rather than the interface. If you can't justify it, use the interface.
我会稍微扭转这个问题,而不是证明为什么应该使用接口而不是具体实现,而是尝试证明为什么要使用具体实现而不是接口。如果您无法证明其合理性,请使用接口。
回答by Arec Barrwin
The less popular answer is programmers like to pretend their software is going to be re-used the world over, when infact the majority of projects will be maintained by a small amount of people and however nice interface-related soundbites are, you're deluding yourself.
不太受欢迎的答案是程序员喜欢假装他们的软件将在全世界重复使用,事实上,大多数项目将由少数人维护,无论与界面相关的声音多么好,你都在自欺欺人你自己。
Architecture Astronauts. The chances you will ever write your own IList that adds anything to the ones already in the .NET framework are so remote that it's theoretical jelly tots reserved for "best practices".
建筑宇航员。您编写自己的 IList 向 .NET 框架中已有的 IList 添加任何内容的机会非常渺茫,以至于它只是为“最佳实践”保留的理论果冻。
Obviously if you are being asked which you use in an interview, you say IList, smile, and both look pleased at yourselves for being so clever. Or for a public facing API, IList. Hopefully you get my point.
很明显,如果你被问到你在面试中使用哪个,你会说 IList,微笑,两个人都为自己如此聪明而感到高兴。或者对于面向公众的 API,IList。希望你明白我的意思。