Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

Suppose I have a method

public List<User> GetBatchOfUsers(IEnumerable<int> userIDs)
{
    List<User> users = new List<User>();

    // some database stuff

    return users;
}

I have read that it would be better to return an interface (either IList or IEnumerable) as opposed to returning a List. Some arguments I have heard for doing so is that it hides data, and gives the API developer the flexibility of changing the internal representation of the data at a later date.

My concern about just returning an IEnumerable is that you lose functionality, such as random access and the Count property.

I know that accepting an IEnumerable as a parameter makes sense, as it gives the consumer the best flexibility to send data to my method, the minimalist set of requirements for the method to operate.

What is the best practice for the return type?

share|improve this question
5  
Far more important: take an interface as parameter type. –  Michael Borgwardt Aug 8 '12 at 7:40
add comment

4 Answers

up vote 6 down vote accepted

Generally speaking, you may start with interfaces, and only move to put the concrete type as the return type if you find that you use the extra methods more frequently than expected.

Well, if you return an interface, you retain more flexibility. You can change the implementation later to return a different concrete type. On the other hand, it obviously gives the caller less information, so they may not be able to perform certain operations. (For example: if you return List<T>, the caller can use ConvertAll etc... which they can't if you only declare that you return IList<T>.) In some situations it's worth specifying the concrete type.

Regarding Count or Sort method, there is no standard collection interfaces for that . However, you could write an extension method to sort or count any IList.

share|improve this answer
    
I guess this isn't really a hard rule then? –  Matthew Aug 8 '12 at 3:43
    
yes, it really depends on usage. –  Yusubov Aug 8 '12 at 3:54
add comment

If You need your collection to have a Count you can use ICollection<T>, which is general enough.

share|improve this answer
    
-1. Count was already discussed and this answer adds nothing new –  superM Aug 8 '12 at 7:36
    
@Konrad Rudolph, this is not an answer, its a comment. –  superM Aug 8 '12 at 10:56
    
@superM It’s valuable enough to merit its own answer, I think, since it explicitly addresses OP’s reason for deciding against interfaces in the first place. –  Konrad Rudolph Aug 8 '12 at 10:59
add comment

You return what is prudent for the method you're defining. Is what you're doing returning a series of items (the focus is on the items), or is it returning a collection of items (the focus is on the collection as a whole)? Is it worthwhile to allow variance in the implementation of the collection? If it will never make sense to use a generator or HashSet then just use the List.

share|improve this answer
add comment

Specific to the example method: You're right that returning IEnmuerable<T> would mean you would lose the functionality of Count and indexing (although you could use LINQ methods Count() and ElementAt(), which are implemented efficiently if the type they're used on actually implements IList<T>).

If you returned IList<T>, you would lose some functionality, but the gain in generality is probably worth it.

But even better would be something between IEnumerable<T> and IList<T>, because it most likely doesn't make sense for the consumer to mutate the returned collection, but it does make sense for him to use Count or indexing.

In .Net 4.5, there is such interface: IReadOnlyList<T>.

share|improve this answer
    
IReadOnlyList sounds good when I can get VS2013, thanks! –  Matthew Aug 8 '12 at 13:20
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.