views:

397

answers:

8

In other words, is it correct to use:

public class CustomerList : System.Collections.Generic.List<Customer>
{
    /// supposed to be empty
}

instead of:

using CustomerList = System.Collections.Generic.List<Customer>

I'd rather use the first approach because I'd just define CustomerList once, and every time I needed a customer list I'd always use the same type. On the other hand, using the name aliasing approach not only forces me to have to redefine it everywhere, but also a different alias could be given every time someone wanted to use it (think of a big team), and thus cause the code to be less readable.

Please note that the intention in this case would never be to extend the class, just to create an alias.

+9  A: 

well, unless you are adding some functionality to the base class there is no point in creating a wrapper object. I would go with number two if you really need to, but why not just create a variable?

List<Customer> customerList = new List<Customer>();
Ed Swangren
I agree with 'just use a variable' but don't think you should advocate using an alias in the way @Trap wants to use it.
Robert Paulson
That's true, I wouldn't do it, but I wasn't exactly sure why he would need to do either in the first place, and that was the question.
Ed Swangren
A: 

This is one of those 'It depends' questions.

If what you need is a new class that behaves as a List of Customers in addition to your other requirements then the inheritance is the way.

If you just want to use a list of customers then use the variable.

Brody
+1  A: 

If you're just trying to save on typing, then use the latter. You're not going to run into any bizarre inheritance issues that way.

If you actually want to expose a logically distinct collection type, then use the former - you can go back and add stuff to it then.

Personally, i would just use List<Customer> and call it a day.

Shog9
A: 

I essentially agree with Ed. If you don't need to actually extend the functionality of the generic List construct, just use a generic List:

List<Customer> customerList = new List<Customer>();

If you do need to extend the functionality then typically you would be looking at inheritance.

The third possibility is where you need significantly changed functionality from the generic list construct, in which case you may want to simply inherit from IEnumerable. Doing so make the class usable in enumerable operations (such as "foreach") but allows you to completely define all class behaviour.

Dr8k
+1  A: 

One programmer's saving on typing could very well be the next programmer's maintenance nightmare. I'd say just type out the generic correctly, as so many here have said. It's cleaner and a more accurate description of your code's intent, and it will help the maintenance programmer. (Who might be you, six months and four new projects down the road!)

John Rudy
+2  A: 

Actually you shouldn't use either. The correct approach according to the framework design guidelines is to either use or inherit from System.Collections.ObjectModel.Collection<T> in public APIs (List<T> should only be used for internal implementation).

But with regards to the specific issue of naming, the recommendation appears to be to use the generic type name directly without aliasing unless you need to add functionality to the collection:

Do return Collection<T> from object models to provide standard plain vanilla collection API.

Do return a subclass of Collection<T> from object models to provide high-level collection API.

Greg Beech
+4  A: 

Don't do it. When people read:

List<Customer>

they immediately understand it. When they read:

CustomerList

they have to go and figure out what a CustomerList is, and that makes your code harder to read. Unless you are the only one working on your codebase, writing readable code is a good idea.

Hallgrim
+3  A: 

I'd agree with not using an alias in that manner. Nobody in your team should be using aliases in the manner presented; it's not the reason aliasing was provided. Additionally, from the way generics work, there is only ever one List class no matter how many places you use it.

In addition to just declaring and using List<Customer>, you're going to eventually want to pass that list to something else. Avoid passing the concrete List<Customer> and instead pass an IList<Customer> or ICollection<Customer> as this will make those methods more resilient and easier to program against.

One day in the future, if you really do need a CustomerList collection class, you can implement ICollection<Customer> or IList<Customer> on it and continue to pass it to those methods without them changing or even knowing better.

Robert Paulson