Why use IList or List?
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>
.
When to use IList and when to use List
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>.
ListT or IListT
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.
Why should I return IListT over ListT?
The reason is so that your method can be used with anything that implements IList<T>
, and not just a List. It gets even worse, though, since the advent of Linq, I've started making a lot of stuff return Enumerable<T>
or even just IEnumerable
!
I am not sure I understand the difficulty, though. If something is returning an actual list, and its return depends on that, or its use is specific to that, then it should return List<T>
. If not, then you should have no need to cast it to a List.
What is the difference between returning IList vs List, or IEnumerable vs ListClass. I want to know which is better to return
There is no such a type that is always better to return. It's a decision you should make based on your design/performance/etc goals.
IEnumerable<T>
is nice to use when you want to represent sequence of items, that you can iterate over, but you don't want to allow modifications(Add, Delete etc).
IList<T>
gives you everything you could get using IEnumerable<T>
, plus operations that give you more control over a collection: Add, Delete, Count, Index access etc.
List<T>
is a concrete implementation of IList<T>
. I would say that almost always it's better to expose IList<T>
interface from your methods rather that List<T>
implementation. And it's not just about lists - it's a basic design principle to prefer interfaces over concrete implementations.
Ok, now about non-generic versions IEnumerable, IList, List
:
They actually came from very early versions of .NET framework, and life is much better using generic equivalents.
And few words about performance:IEnumerable<T>
(with IEnumerator<T>
) is actually an iterator which allows you to defer some computations until later. It means that there is no need to allocate memory right away for storing amounts of data(of course, it's not the case when you have, say, array behind iterator). You can compute data gradually as needed. But it means that these computations might be performed over and over again(say, with every foreach
loop). On the other hand, with List you have fixed data in memory, with cheap Index and Count operations. As you see, it's all about compromise.
Related Topics
C# - Which Is the Best Alternative to 'Switch on Type'
Case-Insensitive Dictionary with String Key-Type in C#
How to Parse Dates with a Suffix "Th", "St" or "Nd" on the Day of the Month
How to Make Form1 Label.Text Change When Checkbox on Form2 Is Checked
How to Check If a Number Is Positive or Negative in C#
How to Overload the [] Operator in C#
How to Select a Random Value from an Enumeration
Center Messagebox in Parent Form
C# - Outputting Image to Response Output Stream Giving Gdi+ Error
How to Programmatically Limit Bandwidth Usage of My C# Application
Prevent C# App from Process Kill
How to Programmatically Limit My Program's CPU Usage to Below 70%
In C#, Is "This" Keyword Required
How to Programmatically Log in to a Website to Screenscape
Execute Unit Tests Serially (Rather Than in Parallel)
How to Generate Unique Public and Private Key via Rsa