Date: 2002-April
Author: (luKa)
Environent: .NET Framework v1.0
Download Examples
Why implement a new collection?
The .Net Framework offers many colletions for all the uses, so why should you
need to implement a new collection?
- To implement a business object that's also a container
In example an Orders class with a 1 to many aggregation relationship with
Order class, an Order class with a 1 to many composition relationship with
OrderItem class or a Customer class with a simple 1 to many relationship with
PaymentOption class.
- To implement an efficent collection of Value-Type elements
Collectons in the Framework are made for Object type generic elements.
To avoid continuous Boxing and Unboxing for Value-Type elements and
performance consequences you need a collection with elements of the
specific Value-Type in the interface parameters but also in the inner implementation.
How to implement a collection with inheritance
In System.Collections and System.Collections.Specialized namespaces there are
abstract base classes to inherit from.
They have
virtual methods you can
override, they have weak-typed
methods with
explicit interface implementation so you can define strong-type
methods in your class, they have
protected virtual methods you can code to
customize the behaviour (validation, etc.) and at the end you can always
hide
the other methods of the base class with no parameters and only a return value.
Here is the list of the
abstract base classes you can inherit from:
See examples:
- COLLECTIONBASE.CS inherits from CollectionBase.
An utility is available to automagically generate the source code:
CollGen.zip
for Beta2
and
CollGen.zip for Release 1 (local)
- READONLYCB.CS inherits from ReadOnlyCollectionBase.
- DICTIONARYBASE.CS inherits from DictionaryBase.
How to implement a collection with containment
Write your own implementation of the collection from scratch, just implement
the interfaces needed by a collection: all the collections must implement
IEnumerable
interface that's extended by
ICollection. Then you can choose from two interfaces
derived from
ICollection:
IDictionary and
IList.
IList interface
is for collections of values. The interface
IDictionary is for collections of (Key, Value) pairs.
The VS.NET Add-In ".NET CollectionGen" is available to automagically generate
source code. See:
http://www.sellsbrothers.com/tools/default.aspx
Download Add-In from:
http://www.sellsbrothers.com/tools/collectiongen.zip
(local)
See examples:
- INNERARRAY.CS use Add-In generated code for an IList collection with an inner strong-typed Array.
- INNERHASH.CS use Add-In generated code for an IDictionary collection with an inner HashTable.
How to choose between collection implementation with inheritance or containment
Inheritance is better suited to model structural facts that are immutable, it's an Is-A relationship.
Containment is suited to model non-structural facts, it's an Has-A relationship.
- With inheritance you need to write less code
- Containment let you improve performance avoiding Boxing/Unboxing
- Containment let you full control and pose no limitation, i.e. you
can code a class that implemnt 2 different collections
- Containment protect you from future changes
that MS could (even if sholdn't...) made to interfaces of base classes for
collections.
Here is the decision tree:
- If you need a Value-Type collection (structure included)
with excellent performances, use containment
- otherwise... if you need to implements multiple collections in
a class, use containments
- otherwise... use inheritance.
If you are in doubt... implement th collection with inheritance.