4 chap07
Jason Zhu edited this page 2021-08-11 12:44:57 +10:00

Chapter 7. Collections

.NET provides multiple standard types to store and manage collections of objects. e.g. resiable list, link lists, sorted and unsorted dictionaries, array

  • Only array is part of C# language, while others are classes
  • these types can be categorized in 3:
    • Interfaces that define standard collection protocols
    • Ready-to-use collection classes (e.g. lists)
    • Base classes for buiding app-specific collections

7.1 Enumeration

All collections regardless complexity (e.g. simple array, or linked list, to complex hashtables) requires the ability to traverse the contents of the collection.

  • .NET BCL support this feature through interfaces IEnumeable and IEnumerator
  • This interface expose a common traversal API

Picture: set of collection interfaces Collection Interfaces

7.1.1 IEnumerable and IEnumerator

IEnumerator

IEnumerator interface defines the basic low-level protocol:

  • collection elements are traversed/enumerated in forward only manner

Declaration of IEnumerator interface:

public interface IEnumerator
{
    bool MoveNext(); // Advances the current element "cursor" to next position
    object Current { get; } // returns element at current position
    void Reset();
}
  • Reset() mainly used for Component Object Mdoel (COM) interperability; It's not universally supported

IEnumerable

  • Enumerator are usually not directly implmented by collections.
  • More often, collections provide enumerator (i.e. IEnumerator) by implementing interface IEnumerable

Declaration of IEnumerable

public interface IEnumerable
// Act as IEnumerator Provider
{
    IEnumerator GetEnumerator(); // Single method return an enumerator
}

Benefit of GetEnumerator():

  1. IEnumerable provides flexibility that iteration logic can be transferred to another class
  2. Several consumers can enumerate the collection at once without interfering with another.

e.g. use IEnumerable & IEnumerator:

string s = "Hello"; // string implement IEnumerable interface

// Because string implements IEnumerable, we can call GetEnumerator();
IEnumerator rator = s.GetEnumerator();

while (rator.MoveNext())
{
    char c = (char) rator.Current;
    Console.Write(c + "."); // Output H.e.l.l.o
}

C# provide foreach as syntax shortcut for using IEnumerable interface (i.e. declare IEnumerator first then .MoveNext())

e.g. syntax shortcut

string s = "Hello";
foreach (char c in s)
{
    Console.Write(c + ".");
}

7.1.2 IEnumerable<T> and IEnumerator<T>

Extended generic versions of IEnumerable<T> and IEnumeratlr<T> provides benefits:

  1. strong static type safety
  2. avoid overhead of boxing
  3. More convenient to consumer

Note:

  • Array implement IEnumerable<T> automatically
  • foreach works on IEnumerable<T> pretty well

e.g. declare of generic IEnumerable<T> and IEnuemrator<T>

public interface IEnumerator<T> : IEnumerator, IDisposable
{
    T Current { get; }
}
public interface IEnumerable<T> : IEnumerable
{
    IEnumerator<T> GetEnumerator();
}

e.g. effect of type safety

void Test(IEnumerable<int> number) {...}

Test("Hello"); // Compile-time error

IEnumerable<T> and IDisposable

IEnumerable<T> inherits from both interface of IEnumerable and IDisposable, provide benefit:

  • Enumerator hold references to resources such as database connections
  • Ensure that resources are released when enumeration is complete

foreach as syntax shortcut recorgnize it and perform follow transform

foreach (var element in somethingEnuemrable) {...}

// Translate to

using (var rator = somethingEnumerable.GetEnumerator())
// ensure disposal
{
    while (rator.MoveNext())
    {
        var element = rator.Current;
        ...
    }
}

TODO: Details are in book, not summarized

7.1.3 Implementing the Enumeration Interfaces

7.2 The ICollection and IList Interfaces

7.2.1 ICollection<T> and ICollection

7.2.2 IList<T> and IList

7.2.3 IReadOnlyCollection<T> and IReadOnlyList<T>

7.3 The Array Class

7.4 List, Queues, Stacks and Sets

7.5 Dictionaries

7.6 Customizable Collections and Proxies

7.7 Immutable Collections

7.8 Plugging in Equality and Order