Classes with Collections as Properties vs. Classes

2019-04-23 17:31发布

问题:

Recently I used a class that inherits from a collection instead of having the collection instantiated within the class, is this acceptable or does it create unseen problems further down the road? Examples below for the sake of clarity:

public class Cars : List<aCar>

instead of something like:

public class Cars
{
 List<aCar> CarList = new List<aCar>();
}

Any thoughts?

回答1:

The problem with this is that your Cars class will still have the interface it inherits from List, which may allow operations you don't want.



回答2:

That depends on the final purpose of your class. If it is only going to work as your own implementation of a collection use inheritance. If not, include a a collection as a property. The second option is more versatile:

  • As you can only inherit from one class, you might need to inherit from another class rather than collection
  • If you need to see this class as a collection you can include an indexer property.


回答3:

I misread the question previously.

I would suggest using composition instead of inheritance. If you want to be able to use all the funky LINQ stuff, by all means implement IEnumerable<T> and perhaps even IList<T> - but I wouldn't derive from List<T> directly.

If you do want to get the collection stuff "for free" but still retain control, you could use CollectionBase. That still ties you down in terms of your one shot at inheritance, but at least you get more control over what happens in the collection.



回答4:

If you want your Cars class to act just like a List and to have the same methods than it isn't that bad. You just derive from it and you're done. Then if you want to add any additional functionality, you can just declare those methods and you're done. However, you're now bound to List and if List changes in any undesirable ways, you're screwed.

When you make it a composite class instead and have the List instantiated inside the class then you only need tp expose the methods of List that you want exposed. But that means that you have to repeat them all too.



回答5:

If the purpose of the class is to add additional functionality to a standard collection, then I would inherit from the collection. If the collection is just one part of a bigger picture, then that sounds more like a property.

I would, however, consider using Collection<T> instead of List<T> unless you really need the functionality in List<T>.



回答6:

Is the "Cars" class really required? Has some added functionality than "List" ? If not, you should use "List" ( or better "IList" ).

If class "Cars" has any added functionality, there is two main scenarios:

  • This class is "final" class, there is no big possibility, the someone others need extended it. Then is this construction OK.
  • This class will be probably used as base class. Then I recommend use this construction:

.

public class CarList<T> : List<T> where T : Car {
    // some added functionality
}

If you want be more flexible in future, you should use a composition:

public class CarList<T> : IList<T> where T : Car {
    private IList<T> innerList;
    public CarList() { this.innerList = new List<T>(); }

    // implementation of IList<T>

    // some added functionality
}