views:

91

answers:

4

I've noticed in other people's code that methods returning generic collections will almost always return an interface (e.g. IEnumerable or IList) rather than a concrete implementation.

I have two related questions. Firstly, why (if at all) is it considered better to return an interface? Secondly, is there a collection interface that includes the Sort method (as List does)?

+5  A: 

For the first question: 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. (e.g. 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; I generally prefer to at least start with interfaces, and only move to put the concrete type as the return type if I find that I frequently want to use the extra methods available.

Secondly, no standard collection interfaces have a Sort method. On the other hand, you could write an extension method to sort any IList<T>. Personally I usually prefer the LINQ OrderBy, OrderByDescending, ThenBy and ThenByDescending methods... although they return a new sequence, rather than sorting in place.

Jon Skeet
Jon, you answered the last three questions I took a look at. Is there a question on SO you haven't seen/asnwered? You ARE a robot! :)
Slavo
Brilliant! Thank you for the clear answer to my question.
David
A: 

I can't speak for everyone but generally I do it just because I like to only return what I need.Why pass back a full blown collection when all you need is an enumerable collection that can be iterated over.

As to the other part of your question you can always use an IList and then use LINQ to sort:

list.OrderBy(a=>a.Id);
spinon
@downvoter care to comment??
spinon
Thanks, I get it now. I didn't know that I had OrderBy available because it's an extension method, and I wasn't using the namespace.
David
Great. Yeah the extension methods for LINQ are great.
spinon
@spinon: Sure, I'll comment on my down vote: I can equally argue that, as a caller, I would prefer to have the most specific collection type returned to me. If the code returns a `List<T>` then I can use it as is, or as an `IList<T>` or `IEnumerable<T>`, etc. It gives the caller more choices. But that's not the real issue here. It's guarding against breaking the calling code if the method's implementation changes. If the method returns an `IEnumerable<T>` then I can change the implementation to use any container that supports that interface without requiring the calling code to be modified.
ShaderOp
@ShaderOp I don't understand. The collection is specific based on the type in the collection, not of the containing item. The containing item just determines what functionality is available to you. But if you need more functionality you can always just create a new list based on the ilist. I don't think I am understanding your argument because I can't figure out if you are saying it is good or bad. Thanks for the comment back though. Was interested what the thinking was.
spinon
@spinon: I'm arguing that the reasoning you presented is wrong. It's not really about the calling code getting access to just what it needs, since--as I have argued--it would make equally as much sense to give the calling code more options and let it take its pick. As already stated, the real reason to prefer returning an `IEnumerable` instead of a concrete `List` is to protect the calling code from implementation changes. Sorry, but I think the distinction is very important.
ShaderOp
@ShaderOp No need to apologize about the downvote. If that's how you felt that's how you felt. I was just curious as why the downvote because my answer seemed in line with what everyone else was saying. Note the last sentence in the first paragraph of the selected answer. That user mentioned the similar thought. Only return the minimum for what you actually need. If you find that you need more options then you can return more. But anyways, thanks for the reason.
spinon
A: 

From C# - List or IList

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 user's 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 may be ok.

LnDCobra
Thank you for this - very helpful. And this is the thing - I'm not writing a library for external usage. I'm writing an intranet for a company in which I am the only developer. It can make it harder for me to see the purpose in some of these things.
David
Yes, if its purely internal, and your definately sure it will not be exposed to the public or multiple parts of your software, then returning a List<T> object should be fine. But if for instance its a class library, and although its used in your application only for now, you may want to extend your application and use that library again, therefore then you will be constrained to List<T> rather then your own implemnentation.
LnDCobra
A: 

We use interfaces to give us more flexibility in our implementation. So if your method has the return type of IEnumerable, you could change the object that it returns from a List to an Array without altering the objects that depend on the method.

It's also expressive: if you are returning an IEnumerable, when the object is being used it's clear to the coder that we only care that it's some sort of collection, rather than a specific type

Jonny Cundall