You want to enhance the performance of your application as well as make the code easier to work with by replacing all ArrayList
objects with the generic version. This is imperative when you find that structures or other value types are being stored in these data structures, resulting in boxing/unboxing operations.
Replace all occurrences of the System.Collection.ArrayList
class with the more efficient generic System.Collections.Generic.List
class.
Here is a simple example of using a System.Collections.ArrayList
object:
public static void UseNonGenericArrayList() { // Create and populate an ArrayList. ArrayList numbers = new ArrayList(); numbers.Add(1);// Causes a boxing operation to occur numbers.Add(2);// Causes a boxing operation to occur // Display all integers in the ArrayList. // Causes an unboxing operation to occur on each iteration foreach (int i in numbers) { Console.WriteLine(i); } numbers.Clear(); }
Here is that same code using a System.Collections.Generic.List
object:
public static void UseGenericList() { // Create and populate a List. List<int> numbers = new List<int>(); numbers.Add(1); numbers.Add(2); // Display all integers in the ArrayList. foreach (int i in numbers) { Console.WriteLine(i); } numbers.Clear(); }
Since ArrayLists
are used in almost all applications, it is a good place to start to enhance the performance of your application. For simple implementations of the ArrayList
in your application, this substitution should be quite easy.
Table 4-1 shows the equivalent members that are implemented in both classes.
Table 4-1. Equivalent members in the ArrayList and the generic List classes
Equivalent members in the generic List class | |
---|---|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| N/A |
|
|
|
|
N/A |
|
|
|
|
|
|
|
| |
N/A |
|
|
|
N/A |
|
N/A |
|
N/A |
|
N/A |
|
N/A |
|
N/A |
|
N/A |
|
| N/A |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
|
|
|
| Use a |
|
|
|
|
|
|
|
|
|
|
N/A |
|
|
|
N/A |
|
In several cases within Table 4-1, there is not a one-to-one correlation between the members of an ArrayList
and the members of the generic List
class. Starting with the properties, notice that only the Capacity
, Count
, and Item
properties are present in both classes. To make up for the missing properties in the List
class, you can perform a cast to an IList
. The following code shows how to use these casts to get at the missing properties:
List<int> numbers = new List<int>(); Console.WriteLine(((IList)numbers).IsReadOnly); Console.WriteLine(((IList)numbers) IsFixedSize); Console.WriteLine(((IList)numbers).IsSynchronized); Console.WriteLine(((IList)numbers).SyncRoot);
Note that due to the absence of code that returns a synchronized version of a generic List
and the absence of code that returns a fixed-size generic List
, the IsFixedSize
and IsSynchronized
properties will always return false
. The SyncRoot
property will always return the same object on which it is called. Essentially, this property returns the this pointer. Microsoft has decided to remove the ability to create a synchronous wrapper from any of the generic collection classes. Instead, they recommend using the lock
keyword to lock the entire collection or another type of synchronization object that suits your needs.
The ArrayList
has several static methods to which there is no direct equivalent method in the generic List
class. To fix this, you have to do a little work. The closest match for the static ArrayList.ReadOnly
method is the AsReadOnly
instance method of the generic List
class. This makes for a fairly simple substitution.
The static ArrayList.Repeat
method has no direct equivalent in the generic List
class. So instead, you can use the following generic extension method:
public static void Repeat<T>(this List<T> list, T obj, int count) { if (count < 0) { throw (new ArgumentException( "The count parameter must be greater or equal to zero.")); } for (int index = 0; index < count; index++) { list.Add(obj); } }
This generic extension method has three parameters:
- list
Marks this method as an extension method for
List<T>
.- obj
The object that will be added to the generic
List
object a specified number of times.- count
The number of times to add the object contained in
obj
to the genericList
object.
Since the Clone
method is also missing from the generic List
class (due to the fact that this class does not implement the ICloneable
interface), you can instead use the GetRange
method of the generic List
class:
List<int> oldList = new List<int>(); // Populate oldList... List<int> newList = oldList.GetRange(0, oldList.Count);
The GetRange
method performs a shallow copy (similar to the Clone
method of the ArrayList
) of a range of elements in the List
object. In this case, the range of elements includes all elements.
Get C# 3.0 Cookbook, 3rd Edition now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.