CHAPTER 9 COLLECTIONS AND GENERICS
Formally speaking, you call these tokens type parameters; however, in more user-friendly terms, you
can simply call them placeholders. You can read the symbol as “of T.” Thus, you can read
IEnumerable as IEnumerable of T; or, to say it another way, IEnumerable of type T.
Note The name of a type parameter (placeholder) is irrelevant, and it is up to the developer who created the generic
item. However, typically T is used to represent types, TKey or K is used for keys, and TValue or V is used for values.
When you create a generic object, implement a generic interface, or invoke a generic member, it is
up to you to supply a value to the type parameter. You’ll see many examples in this chapter, and
throughout the remainder of the text. However, to set the stage, let’s see the basics of interacting with
generic types and members.
Specifying Type Parameters for Generic Classes/Structures
When you create an instance of a generic class or structure, you specify the type parameter when you
declare the variable and when you invoke the constructor. As you saw in the preceding code example,
UseGenericList() defined two List objects:
// This List<> can hold only Person objects.
List morePeople = new List();
You can read the preceding snippet as a List<> of T, where T is of type Person. Or, more simply, you
can read it as a list of person objects. After you specify the type parameter of a generic item, it cannot be
changed (remember: generics are all about type safety). When you specify a type parameter for a generic
class or structure, all occurrences of the placeholder(s) are now replaced with your supplied value.
If you were to view the full declaration of the generic List class using the Visual Studio object
browser, you would see that the placeholder T is used throughout the definition of the List type.
Here is a partial listing (note the items in bold):
// A partial listing of the List class.
namespace System.Collections.Generic
{
public class List :
IList, ICollection, IEnumerable, IReadOnlyList
IList, ICollection, IEnumerable
{
...
public void Add(T item);
public ReadOnlyCollection AsReadOnly();
public int BinarySearch(T item);
public bool Contains(T item);
public void CopyTo(T[] array);
public int FindIndex(System.Predicate match);
public T FindLast(System.Predicate match);
public bool Remove(T item);
public int RemoveAll(System.Predicate match);
public T[] ToArray();
public bool TrueForAll(System.Predicate match);
335