The more you know – Why List<T> is bad with query results
I’ve done a lot of work with LINQ to Data lately (both LINQ to SQL and others). I spend more then the better part of a day checking my Google Reader checking for blog posts and/or articles from the .NET community. There’s a lot you can learn going through some of these sites and a lot you shouldn’t.
One thing I’ve noticed a lot of sites doing (won’t name any) is that when they show off their DAL/BLL I see them returning a List<T> from their query results. Am I the only one that sees the problem there? Returning an actual List<T> object allows the consumer of your query results to actually mess with the order, remove items and do whatever they want with the resulting item list. This is a very bad thing.
When you return your query results you should be returning the results they asked for and nothing more. You should try to hold as much responsibility for the integrity of the data being returned and try to not allow data results to be messed with. If the consumer of your service/repository wants to make it into a list then that’s their responsibility, not yours. If you’re wanting to respond with that with something like “But, I want to filter the data down more.” Then please, add a method with some parameters onto your service/repository. The results you obtain should be just that, results. They should need no filtering, sorting, aggregating or changing.
Here are some examples.
public List<Product> GetProducts()
This is, bad. Doing this allows the consumer to manipulate the results. What should happen is something like this.
public IEnumerable<Product> GetProducts()
The simple change here was the return type. Now we’re just returning an IEnumerable<T> instead. If you really wanted to you could return a System.Collections.ObjectModel.ReadOnlyCollection<T> but I’ve heard of people having some performance issues with it in the past so I would just stick with IEnumerable<T>.
So as you can see when you return an IEnumerable<T> the only thing they can do with the returning results without doing some LINQ against it is enumerate them. Which is probably what you want to return.
The more you know – and shooting star!