C#中List<T> 和 IList<T> 的比较

来源:互联网 发布:微博搞笑排行榜 知乎 编辑:程序博客网 时间:2024/04/28 02:10

从stackoverflow上找的几个观点:


【1】

IEnumerable<T> allows you to iterate through a collection. 

ICollection<T> builds on this and also allows for adding and removing items. 

IList<T> also allows for accessing and modifying them at a specific index. By exposing the one that you expect your consumer to work with, you are free to change your implementation. 

List<T> happens to implement all three of those interfaces.

If you expose your property as a List<T> or even an IList<T> when all you want your consumer to have is the ability to iterate through the collection. Then they could come to depend on the fact that they can modify the list.


【2】

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.

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>.


【3】

There are three questions here: what type should I use for a formal parameter? What should I use for a local variable? and what should I use for a return type?

Formal parameters:

The principle here is do not ask for more than you need.

IEnumerable<T> communicates "I need to get the elements of this sequence from beginning to end". 

IList<T> communicates "I need to get and set the elements of this sequence in arbitrary order". 

List<T> communicates "I need to get and set the elements of this sequence in arbitrary order and I only accept lists; I do not accept arrays."

By asking for more than you need, you

(1) make the caller do unnecessary work to satisfy your unnecessary demands, and 

(2) communicate falsehoods to the reader. Ask only for what you're going to use. That way if the caller has a sequence, they don't need to call ToList on it to satisfy your demand.

Local variables:

Use whatever you want. It's your method. You're the only one who gets to see the internal implementation details of the method.

Return type:

Same principle as before, reversed. Offer the bare minimum that your caller requires. If the caller only requires the ability to enumerate the sequence, only give them an IEnumerable<T>.


【4】

The most practical reason I've ever seen was given by Jeffrey Richter in CLR via C#.

The pattern is to take the basest class or interface possible for your arguments and return the most specific class or interface possible for your return types. This gives your callers the most flexibility in passing in types to your methods and the most opportunities to cast/reuse the return values.


0 0
原创粉丝点击