Practical 10: Generics and Collections

CAB201 - Programming Principles

School of Computer Science, Faculty of Science

Generics in C#

Generics provide a way to write reusable code (methods, classes, interfaces) that can work with different types using a placeholder called a type parameter.

The type parameter is specified when the generic code is used, and can be any type (or constrained using where).

static T GetMin<T>(T first, T second) where T : IComparable<T> {
    return first.CompareTo(second) < 0 ? first : second;
}
GetMin(1, 2); // Returns 1
GetMin("a", "b"); // Returns "a"
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Built-in Collections

Generics are commonly used with collections - groups of objects. We have definitely seen the <> syntax before:

List<int> numbers = new List<int>();

C# has built-in collections (beside List) to cater for different needs:

  • Arrays, e.g., int[] numbers = { 1, 2, 3 }; for fixed-size collections
  • Dictionaries, e.g., Dictionary<string, int> ages = new Dictionary<string, int>(); for key-value pairs
  • IEnumerable, e.g., IEnumerable<int> numbers = new List<int>(); for iterating
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Custom Collections

You can also create your own collections using generics. For example, a Stack<T> class (last-in, first-out) can be implemented as follows:

class Stack<T> {
    private List<T> items = new List<T>();
    public void Push(T item) => items.Add(item);
    public T Pop() {
        T item = items.Last();
        items.RemoveAt(items.Count - 1);
        return item;
    }
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

Indexers

Indexers allow you to access elements of a collection using an index. They are similar to properties, but with index parameter(s).

class Stack<T> {
    private List<T> items = new List<T>();
    // index is the index parameter
    public T this[int index] {
        get => items[index];
        set => items[index] = value;
    }
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science

The IEnumerable Interface

The IEnumerable interface is the base interface for all collections in C#. It provides a way to iterate over the elements of a collection via the GetEnumerator method.

Can use yield return to return elements one at a time:

class Stack<T> : IEnumerable<T> {
    public IEnumerator<T> GetEnumerator() {
        // Return elements in reverse order (last-in, first-out)
        for (int i = items.Count - 1; i >= 0; i--) {
            yield return items[i];
        }
    }
}
CAB201 - Programming Principles
School of Computer Science, Faculty of Science