Information Technology Reference
In-Depth Information
Constraints on Type Parameters
In the generic stack example, the stack did not do anything with the items it contained other
than store them and pop them. It did not try to add them, compare them, or do anything else
that would require using operations of the items themselves. There's good reason for that.
Since the generic stack doesn't know the type of the items it will be storing, it cannot know
what members that type implements.
All C# objects, however, are ultimately derived from class
object
, so the one thing the stack
can be sure of about the items it is storing is that they implement the members of class
object
.
These include methods
ToString
,
Equals
, and
GetType
. Other than that, it can't know what
members are available.
As long as your code does not access the objects of the types it handles (or as long as it
sticks to the members of type
object
), your generic class can handle
any
type. Type parameters
that meet this constraint are called
unbounded type parameters
. If, however, your code tries to
use any other members, the compiler will produce an error message.
For example, the following code declares a class called
Simple
with a method called
LessThan
that takes two generic type variables.
LessThan
attempts to return the result of using
the less-than operator. But not all classes implement the less-than operator, so the compiler
produces an error message.
class Simple<T>
{
static public bool LessThan(T i1, T i2)
{
return i1 < i2; // Error
}
...
}
To make generics more useful, you need to be able to supply additional information to the
compiler about what kinds of types are acceptable as arguments. These additional bits of infor-
mation are called
constraints
. Only arguments that meet the constraints can be substituted for
the type parameters.