C# 何时使用 IList 何时使用 List
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17170/
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
When to use IList and when to use List
提问by Rismo
I know that IList is the interface and List is the concrete type but I still don't know when to use each one. What I'm doing now is if I don't need the Sort or FindAll methods I use the interface. Am I right? Is there a better way to decide when to use the interface or the concrete type?
我知道 IList 是接口,List 是具体类型,但我仍然不知道何时使用每一个。我现在正在做的是,如果我不需要使用该接口的 Sort 或 FindAll 方法。我对吗?有没有更好的方法来决定何时使用接口或具体类型?
采纳答案by Lee
There are two rules I follow:
我遵循两个规则:
- Accept the most basic type that will work
- Return the richest type your user will need
- 接受可以工作的最基本类型
- 返回用户需要的最丰富的类型
So when writing a function or method that takes a collection, write it not to take a List, but an IList<T>, an ICollection<T>, or IEnumerable<T>. The generic interfaces will still work even for heterogenous lists because System.Object can be a T too. Doing this will save you headache if you decide to use a Stack or some other data structure further down the road. If all you need to do in the function is foreach through it, IEnumerable<T> is really all you should be asking for.
因此,在编写接受集合的函数或方法时,不要将其编写为接受 List,而是采用 IList<T>、ICollection<T> 或 IEnumerable<T>。即使对于异构列表,通用接口仍然可以工作,因为 System.Object 也可以是 T。如果您决定使用 Stack 或其他一些数据结构,那么这样做可以省去您的麻烦。如果您需要在该函数中执行的所有操作就是通过它进行 foreach,那么 IEnumerable<T> 确实是您应该要求的全部内容。
On the other hand, when returning an object out of a function, you want to give the user the richest possible set of operations without them having to cast around. So in that case, if it's a List<T> internally, return a copy as a List<T>.
另一方面,当从函数中返回一个对象时,您希望为用户提供尽可能丰富的操作集,而无需他们进行转换。因此,在这种情况下,如果它在内部是 List<T>,则将副本作为 List<T> 返回。
回答by swilliams
I don't think there are hard and fast rules for this type of thing, but I usually go by the guideline of using the lightest possible way until absolutely necessary.
我不认为这种类型的事情有硬性规定,但我通常遵循使用最简单的方法的指导方针,直到绝对必要。
For example, let's say you have a Person
class and a Group
class. A Group
instance has many people, so a List here would make sense. When I declare the list object in Group
I will use an IList<Person>
and instantiate it as a List
.
例如,假设您有一个Person
班级和一个Group
班级。一个Group
实例有很多人,所以这里的 List 是有意义的。当我在中声明列表对象时,Group
我将使用 anIList<Person>
并将其实例化为List
.
public class Group {
private IList<Person> people;
public Group() {
this.people = new List<Person>();
}
}
And, if you don't even need everything in IList
you can always use IEnumerable
too. With modern compilers and processors, I don't think there is really any speed difference, so this is more just a matter of style.
而且,如果您甚至不需要所有东西,IList
也可以随时使用IEnumerable
。使用现代编译器和处理器,我认为真的没有任何速度差异,所以这更只是风格问题。
回答by Dan Herbert
In situations I usually come across, I rarely use IList directly.
在我经常遇到的情况下,我很少直接使用 IList。
Usually I just use it as an argument to a method
通常我只是将它用作方法的参数
void ProcessArrayData(IList almostAnyTypeOfArray)
{
// Do some stuff with the IList array
}
This will allow me to do generic processing on almost any array in the .NET framework, unless it uses IEnumerable and not IList, which happens sometimes.
这将允许我对 .NET 框架中的几乎所有数组进行通用处理,除非它使用 IEnumerable 而不是 IList,这有时会发生。
It really comes down to the kind of functionality you need. I'd suggest using the List class in most cases. IList is best for when you need to make a custom array that could have some very specific rules that you'd like to encapsulate within a collection so you don't repeat yourself, but still want .NET to recognize it as a list.
这真的归结为您需要的功能类型。我建议在大多数情况下使用 List 类。IList 最适合您需要创建自定义数组,该数组可能具有一些您希望封装在集合中的非常具体的规则,这样您就不会重复自己,但仍希望 .NET 将其识别为列表。
回答by Mark Cidade
If you're working within a single method (or even in a single class or assembly in some cases) and no one outside is going to see what you're doing, use the fullness of a List. But if you're interacting with outside code, like when you're returning a list from a method, then you only want to declare the interface without necessarily tying yourself to a specific implementation, especially if you have no control over who compiles against your code afterward. If you started with a concrete type and you decided to change to another one, even if it uses the same interface, you're going to break someone else's code unless you started off with an interface or abstract base type.
如果您在单个方法中工作(在某些情况下甚至在单个类或程序集中)并且外部没有人会看到您在做什么,请使用完整的列表。但是如果你正在与外部代码交互,比如当你从一个方法返回一个列表时,那么你只想声明接口而不必将自己绑定到特定的实现,特别是如果你无法控制谁编译你的之后的代码。如果您从一个具体类型开始并决定更改为另一种类型,即使它使用相同的接口,除非您从接口或抽象基类型开始,否则您将破坏其他人的代码。
回答by Jon Limjap
You should use the interface only if you need it, e.g., if your list is casted to an IList implementation other than List. This is true when, for example, you use NHibernate, which casts ILists into an NHibernate bag object when retrieving data.
您应该仅在需要时使用该接口,例如,如果您的列表被强制转换为 List 以外的 IList 实现。例如,当您使用 NHibernate 时,这是正确的,它在检索数据时将 ILists 转换为 NHibernate bag 对象。
If List is the only implementation that you will ever use for a certain collection, feel free to declare it as a concrete List implementation.
如果 List 是您将用于某个集合的唯一实现,请随意将其声明为具体的 List 实现。
回答by tgmdbm
It's always best to use the lowest base type possible. This gives the implementer of your interface, or consumer of your method, the opportunity to use whatever they like behind the scenes.
最好使用尽可能低的基本类型。这为您的接口的实现者或您的方法的使用者提供了在幕后使用他们喜欢的任何东西的机会。
For collections you should aim to use IEnumerable where possible. This gives the most flexibility but is not always suited.
对于集合,您应该尽可能使用 IEnumerable。这提供了最大的灵活性,但并不总是适合。
回答by ICR
I would agree with Lee's advice for taking parameters, but not returning.
我同意李的建议,即接受参数,但不返回。
If you specify your methods to return an interface that means you are free to change the exact implementation later on without the consuming method ever knowing. I thought I'd never need to change from a List<T> but had to later change to use a custom list library for the extra functionality it provided. Because I'd only returned an IList<T> none of the people that used the library had to change their code.
如果你指定你的方法来返回一个接口,这意味着你以后可以自由地更改确切的实现,而消费方法不知道。我以为我永远不需要从 List<T> 更改,但后来不得不更改为使用自定义列表库来获得它提供的额外功能。因为我只返回了一个 IList<T> 使用该库的人都不必更改他们的代码。
Of course that only need apply to methods that are externally visible (i.e. public methods). I personally use interfaces even in internal code, but as you are able to change all the code yourself if you make breaking changes it's not strictly necessary.
当然,这只需要适用于外部可见的方法(即公共方法)。我个人甚至在内部代码中使用接口,但是如果您进行重大更改,您可以自己更改所有代码,因此这不是绝对必要的。
回答by Joe
Microsoft guidelines as checked by FxCop discourage use of List<T> in public APIs - prefer IList<T>.
FxCop 检查的 Microsoft 指南不鼓励在公共 API 中使用 List<T> - 更喜欢 IList<T>。
Incidentally, I now almost always declare one-dimensional arrays as IList<T>, which means I can consistently use the IList<T>.Count property rather than Array.Length. For example:
顺便说一下,我现在几乎总是将一维数组声明为 IList<T>,这意味着我可以始终使用 IList<T>.Count 属性而不是 Array.Length。例如:
public interface IMyApi
{
IList<int> GetReadOnlyValues();
}
public class MyApiImplementation : IMyApi
{
public IList<int> GetReadOnlyValues()
{
List<int> myList = new List<int>();
... populate list
return myList.AsReadOnly();
}
}
public class MyMockApiImplementationForUnitTests : IMyApi
{
public IList<int> GetReadOnlyValues()
{
IList<int> testValues = new int[] { 1, 2, 3 };
return testValues;
}
}
回答by petr k.
You are most often better of using the most general usable type, in this case the IList or even better the IEnumerable interface, so that you can switch the implementation conveniently at a later time.
您通常最好使用最通用的可用类型,在这种情况下是 IList 或更好的 IEnumerable 接口,以便您可以在以后方便地切换实现。
However, in .NET 2.0, there is an annoying thing - IList does not have a Sort()method. You can use a supplied adapter instead:
但是,在 .NET 2.0 中,有一件烦人的事情 - IList 没有Sort()方法。您可以改用提供的适配器:
ArrayList.Adapter(list).Sort()
回答by rajesh
IEnumerable
You should try and use the least specific type that suits your purpose.IEnumerable
is less specific than IList
.
You use IEnumerable
when you want to loop through the items in a collection.
IEnumerable
您应该尝试使用适合您目的的最不具体的类型。IEnumerable
不如IList
.
您可以使用IEnumerable
,当你通过集合中的项目要循环。
IListIList
implements IEnumerable
.
You should use IList
when you need access by index to your collection, add and delete elements, etc...
IListIList
实现IEnumerable
. 当您需要通过索引访问您的集合、添加和删除元素等时,
您应该使用IList
...
ListList
implements IList
.
列表List
工具IList
。