One of my most favorite classes in the .NET Framework has to be the List Class in the System.Collections.Generic namespace. More specifically, the generic list class as List(T) where T represents a generic type. According to Microsoft Developer Network (MSDN), the list class represents a strongly typed list of objects that can be accessed by index. The List class also provides methods to search, sort, and manipulate lists.
Collections Vs. Arrays
In many applications it is desirable to create and manage groups of related objects. The .NET Framework offers two ways to group objects;
- Creating arrays of objects
- Creating collections of objects
Arrays are most useful for creating and working with a fixed number of strongly-typed objects.
Collections provide a more flexible way to work with groups of objects. Unlike arrays, the group of objects you work with can grow and shrink dynamically as the needs of the application change.
If your collection contains elements of only one data type, you can use one of the classes in the System.Collections.Generic namespace. A generic collection enforces type safety so that no other data type can be added to it. When you retrieve an element from a generic collection, you do not have to determine its data type or convert it.
A collection is a class, so you must declare a new collection before you can add elements to it. Here is an example where I created a collection of Guitar objects, and used the add method of the List class, to load the collection with guitar objects;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
BegSr LoadGuitarCollection Access(*Private) DclFLd Guitars Type(List(*Of Guitar)) New() Guitars.Add(*new Guitar("V95693", 1499.95, *new GuitarSpec(Builder.FENDER, "Stratocastor", GuitarType.ELECTRIC, Wood.ALDER, Wood.ALDER, 12, 4 ))) Guitars.Add(*new Guitar("V95142", 1549.95, *new GuitarSpec(Builder.FENDER, "stratocastor", GuitarType.ELECTRIC, Wood.ALDER, Wood.ALDER, 6, 2))) Guitars.Add(*new Guitar("V95698", 1199.95, *new GuitarSpec(Builder.FENDER, "Stratocastor", GuitarType.ELECTRIC, Wood.MAHOGANY, Wood.MAHOGANY, 6, 2))) Guitars.Add(*new Guitar("V95145", 1299.95, *new GuitarSpec(Builder.FENDER, "stratocastor", GuitarType.ELECTRIC, Wood.ALDER, Wood.ALDER, 6, 2))) Guitars.Add(*new Guitar("V95677", 5288.90, *new GuitarSpec(Builder.GIBSON, "Les Paul Signature", GuitarType.ELECTRIC, Wood.MAHOGANY, Wood.MAHOGANY, 6, 2))) Guitars.Add(*new Guitar("V98734", 1949.99, *new GuitarSpec(Builder.GIBSON, "Les Paul Supreme", GuitarType.ELECTRIC, Wood.MAHOGANY, Wood.MAHOGANY, 6,2))) Guitars.Add(*new Guitar("V98735", 2949.99, *new GuitarSpec(Builder.GIBSON, "Les Paul Standard", GuitarType.ELECTRIC, Wood.MAHOGANY, Wood.MAHOGANY, 6,2))) Guitars.Add(*new Guitar("V98735", 3949.99, *new GuitarSpec(Builder.GIBSON, "Trini Lopez ES-335", GuitarType.ELECTRIC, Wood.MAHOGANY, Wood.MAHOGANY, 6,2))) EndSr EndClass |
Sorting
The List class has great sorting capabilities. The List Class contains a Sort method that is easy to use when the collection contains simple value types like strings or integers. However when the collection of objects are complex types, with multiple properties, sorting by the value of specific properties does get a little more complicated. Here is an example;
I created a class called guitar with multiple properties as follows;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
BegClass Guitar Access(*Public) DclFld _serialNumber Type(*String) Access(*Private) DclFLd _price Type(Double) Access(*Private) DclFld _specs Type(GuitarSpec) Access(*Private) BegConstructor Access(*Public) EndConstructor BegConstructor Access(*Public) DclSrParm serialNumber Type(*String) DclSrParm price Type(Double) DclSrParm specs Type(GuitarSpec) _serialNumber = serialNumber _price = price _specs = specs EndConstructor BegProp SerialNumber Type(*String) Access(*Public) BegGet LeaveSr _serialNumber EndGet EndProp BegProp Price Type(Double) Access(*Public) BegGet LeaveSr _price EndGet EndProp BegProp Specs Type(GuitarSpec) Access(*Public) BegGet LeaveSr _specs EndGet EndProp EndClass |
Now, lets say I want to sort a collection of guitar objects by price. With the sort method of the List class I can delegate sorting by price to another class, whose sole purpose is to perform the sort function. I can accomplish this by inheriting from another class in the System.Collections namespace called Comparer and overriding its Compare method.
Here is the class I wrote for this purpose;
1 2 3 4 5 6 7 8 9 10 11 12 |
BegClass SortGuitarsByPrice Extends(Comparer(*Of Guitar)) Access(*Public) BegConstructor Access(*Public) EndConstructor BegFunc Compare Modifier(*Overrides) Type(*Integer4) Access(*Public) DclSrParm xGuitar Type(Guitar) DclSrParm yGuitar Type(Guitar) LeaveSr xGuitar.Price.CompareTo(yGuitar.Price) EndFunc EndClass |
Anytime I need to sort a collection of guitars by price, I can simply pass an instance of the SortGuitarsByPrice class, as an argument to the List Sort method. Here is a code snippet;
1 2 3 4 5 6 |
DclFld _matchingGuitars Type(List(*Of Guitar)) Access(*Private) Dclfld guitarSorter Type(Comparer(*Of Guitar)) guitarSorter = *New SortGuitarsByPrice() _matchingGuitars.Sort(guitarSorter) |
Here is another example for sorting the collection of guitars by builder and model;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
BegClass SortGuitarsByBuilderThenModel Extends(Comparer(*Of Guitar)) Access(*Public) BegConstructor Access(*Public) EndConstructor BegFunc Compare Modifier(*Overrides) Type(*Integer4) Access(*Public) DclSrParm xGuitar Type(Guitar) DclSrParm yGuitar Type(Guitar) If(xGuitar.Specs.Builder.CompareTo(yGuitar.Specs.Builder) <> 0) LeaveSr xGuitar.Specs.Builder.CompareTo(yGuitar.Specs.Builder) ElseIf(xGuitar.Specs.Model.CompareTo(yGuitar.Specs.Model) <> 0) LeaveSr xGuitar.Specs.Model.CompareTo(yGuitar.Specs.Model) Else LeaveSr 0 EndIf EndFunc EndClass |
To Array
Converting the generic list of objects to a simple array of objects can be very handy in a number of situations. For example, a generic list of objects can be very powerful in a web service application. However, it may be necessary to convert the generic list to an array, in order to support Java and other types of web service consumers. To accomplish this the List class also contains a ToArray() method. Here’s a code snippet;
1 2 3 4 5 |
DclFLd Guitars Type(List(*Of Guitar)) New() DclArray guitarArray Type(Guitar) Rank(1) guitarArray = Guitars.ToArray() |
In my next post I’ll discuss the search capabilities of the List class. I’ll also cover the object-oriented design concept of delegation with an example that utilizes the FindAll() method of the list class.